Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm putting together a Unix/Linux semi-portable thread class (i.e. using the pthread library) for a project I'm working on. Part of the project requires the ability to set the priority of certain threads to allow other threads in the same process more CPU time; which is where the pthread_setschedparam function comes in and my class hits a brick wall.

Below is a simple test I put together to illustrate my issue:

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
#include <string.h>
#include <errno.h>
pthread_mutex_t m_mtx;
bool m_goahead;
void dosleep(int millis)
    usleep(millis*1000);
void domsg(const char *msg)
    pthread_mutex_lock(&m_mtx);
    std::cout << msg << std::endl;
    pthread_mutex_unlock(&m_mtx);
void dowait() {
    while (!m_goahead) {
        dosleep(1);
void *fn1(void *param)
    domsg("in fn1...waiting");
    dowait();
    while (m_goahead) {
        dosleep(1000);
        domsg("in fn1 loop");
void *fn2(void *param)
    domsg("in fn2...waiting");
    dowait();
    while (m_goahead) {
        dosleep(1000);
        domsg("in fn2 loop");
int main(int argc, char **argv)
    // min prio = -2, max prio = 2
    int t1_pri = 2, t2_pri = 0, main_pri = 1;
    //SCHED_RR, SCHED_FIFO, SCHED_OTHER (POSIX scheduling policies)
    int sched = SCHED_OTHER; // standard
    // get the range between min and max and set the priorities base on split range
    int min = sched_get_priority_min(sched);
    int max = sched_get_priority_max(sched);
    int skip = (max - min) / 5; // 5 since -2...2
    struct sched_param main_param, t1_param, t2_param;
    memset(&main_param, 0, sizeof(sched_param));
    memset(&t1_param, 0, sizeof(sched_param));
    memset(&t2_param, 0, sizeof(sched_param));
    main_param.sched_priority = (min + ((main_pri+2) * (skip+1))) + (skip / 2);
    t1_param.sched_priority = (min + ((t1_pri+2) * (skip+1))) + (skip / 2);
    t2_param.sched_priority = (min + ((t2_pri+2) * (skip+1))) + (skip / 2);
    std::cout << "main thread will have a prio of " << main_param.sched_priority << std::endl;
    std::cout << "t1 thread will have a prio of " << t1_param.sched_priority << std::endl;
    std::cout << "t2 thread will have a prio of " << t2_param.sched_priority << std::endl;
    m_goahead = false;
    pthread_mutex_init(&m_mtx, NULL);
    pthread_t t1, t2;
    // Create the threads 
    if (pthread_create(&t1, NULL, fn1, NULL) != 0) {
        std::cout << "couldn't create t1" << std::endl;
        return -1;
    if (pthread_create(&t2, NULL, fn2, NULL) != 0) {
        std::cout << "couldn't create t2" << std::endl;
        return -1;
    dosleep(1000); // sleep a second before setting priorities
    // --main thread--
    if (pthread_setschedparam(pthread_self(), sched, &main_param) != 0) {
        std::cout << "error setting priority for main thread: (" << errno << "), " << strerror(errno) << std::endl;
    // --t1 thread--
    if (pthread_setschedparam(t1, sched, &t1_param) != 0) {
        std::cout << "error setting priority for T1: (" << errno << "), " << strerror(errno) << std::endl;
    // --t2 thread--
    if (pthread_setschedparam(t2, sched, &t2_param) != 0) {
        std::cout << "error setting priority for T2: (" << errno << "), " << strerror(errno) << std::endl;
    m_goahead = true; // all start
    // loop until user interupt
    for (;;) {
        dosleep(1000);
        domsg("in main loop");
    pthread_mutex_destroy(&m_mtx);
    return 0;

Base on this code, if I compile this and run it on an OpenBSD system, I get the following:

main thread will have a prio of 24
t1 thread will have a prio of 31
t2 thread will have a prio of 17
in fn1...waiting
in fn2...waiting
in fn1 loop
in main loop
in fn2 loop
in fn1 loop
in main loop
in fn2 loop
in fn1 loop
in main loop
in fn2 loop

Note how it goes in the order of the thread priority, fn1, main, fn2...

If I run this same test on an Ubuntu 10.04LTS system, I get the following:

main thread will have a prio of 3
t1 thread will have a prio of 4
t2 thread will have a prio of 2
in fn1...waiting
in fn2...waiting
error setting priority for main thread: (22), Invalid argument
error setting priority for T1: (22), Invalid argument
error setting priority for T2: (22), Invalid argument
in main loop
in fn2 loop
in fn1 loop
in main loop
in fn2 loop
in fn1 loop
in main loop
in fn2 loop
in fn1 loop

I understand that the invalid argument is because I'm specifying the SCHED_OTHER priority class and trying to assign it any number other than 0; what I cannot figure is how can I make this work properly?

I've tried 'assuming' a SCHED_FIFO or SCHED_RR priority class to get the min/max values, which gives me valid min/max values and I don't get the 'invalid argument' error, but the function loop output is not in the prioritized order, it is instead in whatever order the function happened to get called (to be expected if no priority was set).

Ideally I would get the current process' priority class, then assign the thread on that class too, however, if the current process' priority is SCHED_OTHER then setting a thread based on that produces the invalid results I don't want.

Is there a more 'portable' way to set a thread's priority or grab the valid min/max values? Can I even set a thread's priority under SCHED_OTHER in certain environments, or is that functionality left to said environment?

I'm at an impasse with this problem and would appreciate any insight or pointers in the right direction.

Thanks and please let me know if my code/explanation is unclear.

Refer this if it helps increase understanding. But what little I learned, SCHED_OTHER is their only to mean that all the non real time thread will have equal priority. But then in the question referred BSD give max and min 0 and 99 even in case of SCHED_OTHER, didn't understand why, but one thing is clear, it is not a very portable and to rely on its exact value will not help. In that case putting special handling will do much better, like if range is [0-0] then using nice(if thread priority can be fixed by nice,please let me know) be used to set the priority.

Thanks

Thanks for info! Unfortunately using nice is only valid on processes and not threads, but from what I can see within the different kernel sources, thread priorities are VERY system dependent; OpenBSD implements the absolute minimum POSIX standard but has a more robust thread scheduler, while Ubuntu implements some non-portable POSIX idioms and has a simpler thread scheduler, where as Solaris only implements the SCHED_OTHER policy. I'm still on a hunt for this.. – txtechhelp May 22, 2012 at 3:55

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.