How to increase thread priority in pthreads?
Solution 1:
The default Linux scheduling policy is SCHED_OTHER
, which have no priority choice but a nice
level to tweak inside the policy.
You'll have to change to another scheduling policy using function pthread_setschedparam
(see also man sched_setscheduler
)
'Normal' scheduling policies: (from sched_setscheduler(2)
)
SCHED_OTHER the standard round-robin time-sharing policy;
SCHED_BATCH for "batch" style execution of processes; and
SCHED_IDLE for running very low priority background jobs.
Real-time scheduling policies:
SCHED_FIFO a first-in, first-out policy; and
SCHED_RR a round-robin policy.
In your case maybe you can use SCHED_BATCH
as this does not require root privileges.
Warning: wrong usage of real-time scheduling policies may hang your system. That's why you need root privileges to do this kind of operation.
Just to be sure of what your machine is capable of, you can use chrt
tool from
util-linux
package.
As an example:
$ chrt -m
SCHED_OTHER min/max priority : 0/0
SCHED_FIFO min/max priority : 1/99
SCHED_RR min/max priority : 1/99
SCHED_BATCH min/max priority : 0/0
SCHED_IDLE min/max priority : 0/0
A way to waste less time (which I often use):
alias batchmake='time chrt --batch 0 make --silent'
While staying with user privileges, this propels the make
by 15% (in my case).
Edit: introducing nice
, SCHED_BATCH
, SCHED_IDLE
and chrt
tool. For accuracy ! :)
Solution 2:
The current answer from levif (recommending SCHED_BATCH) is not correct for the current NPTL thread implementation on Linux (you can check which implementation your kernel has by running 'getconf GNU_LIBPTHREAD_VERSION').
In today's kernel only the Real Time Scheduling policies allow setting of sched_priority - it is always 0 for the non-RT policies (SCHED_OTHER, SCHED_BATCH, and SCHED_IDLE). Your only choice for the non-RT policies is to set 'nice' values e.g. by setpriority(). There are not good specifications of the exact behavior to expect by setting 'nice' however, and at least in theory it could vary from kernel version to kernel version. For current Linux kernels 'nice' has a very strong effect similar to priority, so you can use it pretty much interchangeably. In order to increase how often your thread is scheduled, you want to lower your 'nice' value. This requires CAP_SYS_NICE capability (typically root, although not necessarily, see http://man7.org/linux/man-pages/man7/capabilities.7.html and http://man7.org/linux/man-pages/man3/cap_set_proc.3.html).
In fact SCHED_BATCH is designed for the opposite case to what the questioner requested: it is designed for CPU-intensive, long running jobs, that can live with lower priority. It tells the scheduler to slightly penalize wake-up priority for the threads.
Also to answer one of the earlier comments (I don't yet have sufficient reputation to comment in response - some upvotes for this answer would help :) ). Yes the bad news is that the POSIX.1 specification says that 'nice' affects processes, not individual threads. The good news is that the Linux thread implementations (both NPTL and the original Linux Threads) break the specification and allow it to affect individual threads. I find it amusing that this is often called out in the "BUGS" section of the man pages. I'd say the bug was in the POSIX.1 specification, which should have allowed this behavior, not in the implementations which were compelled to provide it in spite of the specification and did so knowingly and deliberately. In other words - not a bug.
Most of this is detailed on the sched(7) man page (which for some reason is not delivered on my Fedora 20 system): http://man7.org/linux/man-pages/man7/sched.7.html
If you really wanted to affect sched_priority you could look at the Real Time policies such as SCHED_RR).
Solution 3:
POSIX defines a query, so you can ask OS for the valid range of priorities.
int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy);
Don't expect raised priority to choke the machine. In fact, don't expect it to do anything unless you're already using 100% of CPU cycles. Don't be surprised if the query tells you that there is no priority higher than the default.