Set the threads priority in C++11

Asked

Viewed 784 times

8

In the program I’m developing I have two Std::threads that are always active throughout the life of the program. However, I consider that the role of one of them is of minor importance and would like to change their priority.

I took a look at the documentation and found no function that defines the Std::thread priority.

My question is: how do I prioritize an Std::thread? Is it possible or the operating system itself is in charge of defining this at runtime?

Note: The program will only run on Linux (Debian), so there is no need to portability with Windows.

3 answers

5


There is no way to change the priority of a std::thread on C++11 or C++14. The only way to do this would be by using (non-portable) linux functions. Get a native identifier with std::thread::native_handle() and use it with the function pthread_setschedparam. An example (taken from the first reference):

#include <thread>
#include <iostream>
#include <chrono>
#include <cstring>
#include <pthread.h>

std::mutex iomutex;
void f(int num)
{
    std::this_thread::sleep_for(std::chrono::seconds(1));

    sched_param sch;
    int policy; 
    pthread_getschedparam(pthread_self(), &policy, &sch);
    std::lock_guard<std::mutex> lk(iomutex);
    std::cout << "Thread " << num << " executando na prioridade "
              << sch.sched_priority << '\n';
}

int main()
{
    std::thread t1(f, 1), t2(f, 2);

    sched_param sch;
    int policy; 
    pthread_getschedparam(t1.native_handle(), &policy, &sch);
    sch.sched_priority = 20;
    if (pthread_setschedparam(t1.native_handle(), SCHED_FIFO, &sch)) {
        std::cout << "setschedparam falhou: " << std::strerror(errno) << '\n';
    }

    t1.join(); t2.join();
}

In Windows the same idea can be applied with the SetThreadPriority.

5

According to that answer the standard C++11 library does not provide standard support for thread priority control. (The author still believes that this will not change in C++14) In the same answer he cites a command that works in systems that follow the standards POSIX:

pthread_setschedparam(thread.native_handle(), politica, {prioridade});

As you only want for linux, this method should solve your problem. There are still some relevant points to be taken into account.

Standard Linux threads policy has dynamic priority

Generally, when you start a thread, Linux puts the policy SCHED_OTHER, as seen in that SOEN response. In the same answer, he puts the types of policy that can be adopted for the thread system and what is the minimum and maximum priority:

SCHED_FIFO: Queue schema, first in, first out. (1/99)

SCHED_RR: Policy scheme round-Robin. (1/99)

Where the priority is as follows (min/max). I chose to put policies that had priority. Although I read in the comments that the SCHED_OTHER can offer a certain level of priority control, it is defined by the system itself according to the behavior of the thread, what you can do is give "a hint of the importance of the thread", setting its priority as very high (-20) or very low (19).

Policies for thread exchange

Threads with the policies SCHED_RR or SCHED_FIFO will be exchanged if one of the two events happens, still according to this link:

  • A thread is put to sleep (sleep) or you start to expect an event
  • A higher priority real-time thread is ready to run

These points should be taken into account when implementing your threads.

That said, let’s go to our example:

Example taken from the Reference cpp:

#include <thread>
#include <mutex>
#include <iostream>
#include <chrono>
#include <cstring>
#include <pthread.h>

std::mutex iomutex;
void f(int num) {
    std::this_thread::sleep_for(std::chrono::seconds(1));

   sched_param sch;
   int policy; 
   pthread_getschedparam(pthread_self(), &policy, &sch);
   std::lock_guard<std::mutex> lk(iomutex);
   std::cout << "Thread " << num << " esta executando com prioridade "
             << sch.sched_priority << '\n';
}

int main(){
    //A thread 2 será uma thread padrão
    std::thread t1(f, 1), t2(f, 2);

    sched_param sch;
    int policy; 
    pthread_getschedparam(t1.native_handle(), &policy, &sch);
    sch.sched_priority = 20;
    //Nessa linha ele seta a política e a prioridade da thread 1
    if(pthread_setschedparam(t1.native_handle(), SCHED_FIFO, &sch)) {
        std::cout << "Falha para utilizar setschedparam: " << std::strerror(errno) << '\n';
    }

    t1.join(); t2.join();
}

Despite everything, I was left with a doubt, perhaps due to my ignorance of how POSIX systems treat the priorities of threads, but, for what the example puts as output, threads with values taller priority, has priority minor.

Example output:

Thread 2 esta executando com prioridade 0
Thread 1 esta executando com prioridade 20

1

Browser other questions tagged

You are not signed in. Login or sign up in order to post.