69

I am using pthread in Linux. I would like to increase the thread priority by setting the parameters sched_param.priority. However, I could not find much info from the net regarding the range of the thread priority I could set, or about the description of the thread priority.

Also, I would like to know about the relative thread priority as I would not want to set the thread priority to be too high and resulting the OS to halt. Could someone help me with this?

P Shved
  • 96,026
  • 17
  • 121
  • 165
Steveng
  • 1,141
  • 2
  • 11
  • 14

3 Answers3

66

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 ! :)

levif
  • 2,156
  • 16
  • 14
  • 1
    re: `SCHED_OTHER`, this is not entirely correct since nice level still takes effect. – Hasturkun Sep 07 '10 at 22:55
  • @Hasturkun: you're right there is the *nice* tweak, as an advice for the scheduler (not a scheduler priority!). Thanks for accuracy ! – levif Sep 08 '10 at 08:40
  • you don't actually need root privileges, just need to have the rlimits set so that the max prio you're allowed to set is > 0 – Spudd86 Nov 22 '10 at 20:05
  • 2
    @Spudd86: of course, one can tweak the system file `limits.conf` (in /etc/security/ on FC) to increase Hard values and then use setrlimit() as a standard user. Among other cases, this is indispensable for real-time audio mixing. This point was missing, I'll edit to fix. – levif Nov 24 '10 at 18:00
  • that's what I was referring to, yes. You can also raise your nice limit, which would seem to be what would be the appropriate answer to the question, since they don't want to be able lock the machine. – Spudd86 Nov 25 '10 at 18:34
  • seems that "nice" command is for whole programs; cannot one tweak different thread priorities within a single program? – knocte Jan 16 '13 at 23:11
  • The POSIX.1 specification says that nice affects the whole program. However, Linux breaks the specification (as it should!) in order to cause nice to affect individual threads. See my answer in this thread for more details. – BobDoolittle Jul 01 '14 at 16:47
  • SCHED_BATCH has the opposite effect requested. See my answer to this question for more details. – BobDoolittle Jul 01 '14 at 16:52
  • Thanks for this explanation. It really helped me understand a topic that seems obscure even now – DBB Jan 10 '20 at 19:52
40

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).

BobDoolittle
  • 1,326
  • 1
  • 12
  • 21
  • What is/was the "current NPTL thread implementation"? I need something to compare to the output from `getconf` on a legacy target. – jhfrontz Nov 20 '15 at 17:41
  • 4
    NTPL (Native POSIX Threads Library) is what the current Linux thread implementation is called. It differs from the original thread implementation which used multiple processes to simulate multi-threading behavior. NTPL was introduced in Linux 2.6. More details and history here: https://en.m.wikipedia.org/wiki/Native_POSIX_Thread_Library – BobDoolittle Nov 21 '15 at 19:31
  • The difference to the old stupid implementation by Linus was that he used the stackpointer to find the current running thread so it could be implemented with less kernel support. But the implementation so primitive that fibers/green thread who changed the stack to a malloc'ed memory segment broke apart. Luckily it was removed fast. – Lothar Mar 26 '21 at 12:28
29

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.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421