Setting thread priority in C ++ 11

7

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 function of one of them is minor and would like to change their priority.

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

My question is: how do I set the priority of a std :: thread? It is 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.

    
asked by anonymous 05.02.2014 / 01:05

3 answers

4

There is no way to change the priority of a std::thread in C ++ 11 or C ++ 14. The only way to do this would be to use linux (non-portable) functions. Get a native identifier with std::thread::native_handle() and use it with 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();
}

On Windows the same idea can be applied with SetThreadPriority .

    
05.02.2014 / 02:08
5

According to this answer the default library for C ++ 11 does not provide standard support for thread priority control. (The author still believes that this will not change in C ++ 14) In this same answer he cites a command that works on systems that follow the rules 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 take into account.

Linux's default thread policy has dynamic priority

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

  

SCHED_FIFO : Queue schema, first to enter, is the first to exit. (1/99)

     

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

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

Threading Exchange Policies

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

  
  • A thread is either sleeping ( sleep ) or waiting for an event
  •   
  • A higher priority real-time thread is ready to run
  •   

These points should be taken into account when you implement your threads.

Having said that, let's go to our example:

Example taken from cpp reference :

#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();
}

In spite of everything, I was left with a doubt, perhaps because of my lack of knowledge of how POSIX systems handle thread priorities, but, as the example puts, threads with higher values priority, minor priority.

Example output:

Thread 2 esta executando com prioridade 0
Thread 1 esta executando com prioridade 20
    
05.02.2014 / 02:25
1

The way to do this involves getting a handle to the native implementation of the thread. An example of using the std :: thread :: native_handle function is described in link . p>     

05.02.2014 / 02:09