Pthread Priority on Non PREEMPT Linux Kernels

I've recently been exposed to <pthread.h>, which is is a Unix/Linux (POSIX) API for multi-threading. While playing around with the code and trying to prioritize certain threads so that they execute prior to other threads, I realized that my scheduling parameters, although do not return any errors, are being ignored by the the OS. Threads which I've set to the highest priority do not appear to have executed prior to threads with lower priority. I have been previously told that the Linux kernel I am running on has to have the PREEMPT (and possibly the RT) configurations to properly prioritize threads. Is that why my programs are not behaving according to my expectations? int main() { pthread_t tid1, tid2; pthread_attr_t attr; struct sched_param param; pthread_attr_init(&attr); pthread_attr_getschedparam(&attr, &param); param_sched_priority = 99; pthread_attr_setschedpolicy(&attr, &param); pthread_attr_setschedparam(&attr, &param); pthread_create(&tid1, &attr, myFunc1, NULL); pthread_attr_init(&attr); pthread_attr_getschedparam(&attr, &param); param_sched_priority = 1; pthread_attr_setschedpolicy(&attr, &param); pthread_attr_setschedparam(&attr, &param); pthread_create(&tid1, &attr, myFunc2, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); }

3/22/2019 6:07:51 AM


5 Answers

New Answer


It seems to me you are waiting for more answers while I (and maybe others) are waiting for a response, too ^^ Well, I shall attempt an answer without further information then. The suggested code snippet, if run in the threads, should reveal if the scheduler uses a real-time scheduling policy (either FIFO or RR). If it doesn't then setting the thread priority has no effect (in fact, it is required to be zero, which should show in the output). In that case, you can have the threads make a call to `nice` [unistd.h] to adjust their niceness value (the higher the niceness, the lower prioritised the thread will become). Or you can have the threads make a call to `pthread_setschedparam`, which allows to specify the (real-time) scheduling policy. For an explanation of the scheduling policies, have a look at the man page for 'sched(7)'. It seems it is not possible to adjust the policy from the outside (using attributes). So, the information has to be provided via thread start parameter and set by the thread itself [you can get access to the running thread's ID using `pthread_self()`] As far as the "expected behaviour" is concerned, I won't hazard a guess (with multi-core processors and frequent cpu migrations, I wouldn't even know what to expect). Rather than interpreting program behaviour, I would probably rely on the settings - that is, if `pthread_getschedparams` yields real-time scheduling policy with my custom priority settings, then I'd be inclined to believe that.


If you have your thread functions myFunc1 and myFunc2 execute the following lines of code, what is the output? int policy, s; struct sched_param param; s = pthread_getschedparam(pthread_self(), &policy, & param); if(s) { perror("get_schedparam"); } else { printf("myFuncN\npolicy: %s\npriority: %d\n", (policy == SCHED_FIFO ? "SCHED_FIFO" : (policy == SCHED_RR ? "SCHED_RR" : (policy == SCHED_OTHER ? "SCHED_OTHER" : "???"))), param.sched_priority); } [ This is basically taken directly from the Linux man pages ]


Ani Jona 🕊 Sorry for the late reply. The reason I haven't tested your code yet is because the build environment is installed on a machine which I currently have no access to. It will be about two days from now until I can get back to you regarding the output, but I will.


Ani Jona 🕊 I've run the code above and received this output policy: SCHED_OTHER priority: 0 for both functions! I guess this is what was messing things up for me. Does this mean that my Linux config does not support prioritizing threads? How should I change the policy then?


I guess the threads inherit the attribute settings from the parent thread (i.e. the main thread). You could query that using `pthread_attr_getinheritsched`. If the inheritsched attribute is `PTHREAD_INHERIT_SCHED`, then (according to the man pages) the attributes *policy*, *param* and *scope* are ignored. That would account for why the policy setting via attributes doesn't work. Have you tried: 1) To set the policy after thread creation: ``` pthread_t tid; int policy, s; struct sched_param param; pthread_create(&tid, NULL, myFunc, NULL); pthread_getschedparam(tid, &policy, & param); param.sched_priority = 99; s = pthread_setschedparam(tid, SCHED_RR, & param); if(s) { // handle error } ``` 2) Use the same code (except the thread creation part) *inside* the thread (using `pthread_self()` to get the thread id)) - and let the thread adjust its own scheduling policy.