Is Nice() Used to Change the Thread Priority or the Process Priority

is nice() used to change the thread priority or the process priority?

The pthreads man page says:

POSIX.1 also requires that threads share a range of other attributes
(i.e., these attributes are process-wide rather than per-thread):

[...]

  • nice value (setpriority(2))

So, theoretically, the "niceness" value is global to the process and shared by all threads, and you should not be able to set a specific niceness for one or more individual threads.

However, the very same man page also says:

LinuxThreads

The notable features of this implementation are the following:

[...]

  • Threads do not share a common nice value.

NPTL

[...]

NPTL still has a few non-conformances with POSIX.1:

  • Threads do not share a common nice value.

So it turns out that both threading implementations on Linux (LinuxThreads and NPTL) actually violate POSIX.1, and you can set a specific niceness for one or more individual threads by passing a tid to setpriority() on these systems.

thread priority or process priority?

the first line of man 2 nice gives us:

nice - change process priority

Does nice affect the priority of Java threads

Actually...Niceness is a property of the application according to POSIX.1. Here is a more detailed post. is nice() used to change the thread priority or the process priority?

Process Priority vs Thread Priority

Linux implements (kernel level) Threads essentially as Processes. So you fall back to the good old process-priorities there.

See NPTL and nice (for understanding that processes are the first ones to have priorities). Mostly defaults are applied - in case of threads, the thread is a copy, so its priorities should be copied too. Will certainly vary with varying schedulers.

Any relationship between process priority and thread pool priority (C#)

I understand that thread pool priority should/can not be changed by the running process,

That's not exact. You can change Thread Pool's thread priority (inside delegate itself) and it'll run with new priority but default one will be restored when its task finishes and it'll be send back to pool.

ThreadPool.QueueUserWorkItem(delegate(object state) {
Thread.CurrentThread.Priority = ThreadPriority.Highest;

// Code in this function will run with Highest priority
});

is the priority of particular task running on the thread pool somewhat priced-in with the calling process priority?

Yes, and it doesn't apply to Thread Pool's threads only. In Windows process' priority is given by its class (from IDLE_PRIORITY_CLASS to REALTIME_PRIORITY_CLASS). Together with thread's priority (from THREAD_PRIORITY_IDLE to THREAD_PRIORITY_TIME_CRITICAL) it'll be used to calculate thread's final priority.

From MSDN:

The process priority class and thread priority level are combined to form the base priority of each thread.

Note that it's not simply a base priority plus an offset:

NORMAL_PRIORITY_CLASS + THREAD_PRIORITY_IDLE  == 1
NORMAL_PRIORITY_CLASS + THREAD_PRIORITY_TIME_CRITICAL == 15

But:

REALTIME_PRIORITY_CLASS + THREAD_PRIORITY_IDLE == 16
REALTIME_PRIORITY_CLASS + THREAD_PRIORITY_TIME_CRITICAL == 31

Moreover threads can have a temporary boost (decided and managed by Windows Scheduler). Be aware that a process can also change its own priority class.

in other words, do all tasks in thread pool run in the same priority regardless the calling process priority?

No, thread's priority depends on process' priority (see previous paragraph) and each thread in pool can temporary have a different priority. Also note that thread priority isn't affected by caller thread's priority:

ThreadPool.QueueUserWorkItem(delegate(object s1) {
Thread.CurrentThread.Priority = ThreadPriority.Highest;

ThreadPool.QueueUserWorkItem(delegate(object s2) {
// This code is executed with ThreadPriority.Normal

Thread.CurrentThread.Priority = ThreadPriority.Lowest;

// This code is executed with ThreadPriority.Lowest
});

// This code is executed with ThreadPriority.Highest
});

EDIT: .NET tasks uses Thread Pool than what wrote above still applies. If, for example, you're enumerating a collecition with Parallel.ForEach to increase thread priority you have to do it inside your loop:

Parallel.ForEach(items, item => {
Thread.CurrentThread.Priority = ThreadPriority.Highest;

// Your code here...
});

Just a warning: be careful when you change priorities. If, for example, two threads use a shared resource (protected by a lock), there are many races to acquire that resources and one of them has highest priority then you may end with a very high CPU usage (because of spinning behavior of Monitor.Enter). This is just one issue, please refer to MSDN for more details (increasing thread's priority may even result is worse performance).

When should I consider changing thread priority

When you've made a list of the threads you're using and defined a priority order for them which makes sense in terms of the work they do.

If you nudge threads up here and there in order to bodge your way out of a problem, eventually they'll all be high priority and you're back where you started. Don't assume you can fix a race condition with prioritisation when really it needs locking, because chances are you've only fixed it in friendly conditions. There may still be cases where it can fail, such as when the lower-priority thread has undergone priority inheritance because another high-priority thread is waiting on another lock it's holding.

If you classify threads along the lines of "these threads fill the audio buffer", "these threads make my app responsive to system events", "these threads make my app responsive to the user", "these threads are getting on with some business and will report when they're good and ready", then the threads ought to be prioritised accordingly.

Finally, it depends on the OS. If thread priority is completely secondary to process priority, then it shouldn't be "dangerous" to prioritise threads: the only thing you can starve of CPU is yourself. But if your high-priority threads run in preference to the normal-priority threads of other, unrelated applications, then you have a broader responsibility. You should only be raising priorities of threads which do small amounts of urgent work. The definition of "small" depends what kind of device you're on - with a 3GHz multi-core processor you get away with a lot, but a mobile device might have pseudo real-time expectations that user-level apps can break.

Keeping the audio buffer serviced is the canonical example of when to be high priority, though, since small under-runs usually cause nasty crackling. Long downloads (or other slow I/O) are the canonical example of when to be low priority, since there's no urgency processing this chunk of data if the next one won't be along for ages anyway. If you're ever writing a device driver you'll need to make more complex decisions how to play nicely with others.

Does using setpriority() have any affect if my scheduling policy is SCHED_OTHER


The answer is no. The setpriority should not affect the process in this case. As per the documentation:

http://linux.die.net/man/3/setpriority

> Any processes or threads using SCHED_FIFO or SCHED_RR shall be unaffected by a call to setpriority(). This is not considered an error. A process which subsequently reverts to SCHED_OTHER need not have its priority affected by such a setpriority() call.

I'm sorry but reading carefuly the http://man7.org/linux/man-pages/man7/sched.7.html:

SCHED_OTHER: Default Linux time-sharing scheduling
SCHED_OTHER can be used at only static priority 0. SCHED_OTHER is
the standard Linux time-sharing scheduler that is intended for all
threads that do not require the special real-time mechanisms. The
thread to run is chosen from the static priority 0 list based on a
dynamic priority that is determined only inside this list. The
dynamic priority is based on the nice value (set by nice(2),
setpriority(2), or sched_setattr(2)) and increased for each time
quantum the thread is ready to run, but denied to run by the
scheduler. This ensures fair progress among all SCHED_OTHER threads.

Thus, the dynamic priority of the threads is affected by the call to setpriority and it should cause changes in the scheduling (depending on the new priority value being set in the call).

Will the kernel change the nice value of a process?

The linux kernel does not automatically change the nice value - something else did it.

What exactly does thread priority do in Java

From: https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html

Every thread has a priority. Threads with higher priority are executed
in preference to threads with lower priority. Each thread may or may
not also be marked as a daemon. When code running in some thread
creates a new Thread object, the new thread has its priority initially
set equal to the priority of the creating thread, and is a daemon
thread if and only if the creating thread is a daemon.

(as a note: this information was found by searching "java Thread.MAX_PRIORITY" in google and looking at the top result)



Related Topics



Leave a reply



Submit