Portable way of setting std::thread priority in C++11
C++C++11PortabilityStdthreadThread PriorityC++ Problem Overview
What is the correct way in the post C++11 world for setting the priority of an instance of std::thread
Is there a portable way of doing this that works at least in Windows and POSIX (Linux) environments?
Or is it a matter of getting a handle and using whatever native calls are available for the particular OS?
C++ Solutions
Solution 1 - C++
There's no way to set thread priorities via the C++11 library. I don't think this is going to change in C++14, and my crystal ball is too hazy to comment on versions after that.
In POSIX, pthread_setschedparam(thread.native_handle(), policy, {priority});
In Win32 BOOL SetThreadPriority(HANDLE hThread,int nPriority)
Solution 2 - C++
My quick implementation...
#include <thread>
#include <pthread.h>
#include <iostream>
#include <cstring>
class thread : public std::thread
{
public:
thread() {}
static void setScheduling(std::thread &th, int policy, int priority) {
sch_params.sched_priority = priority;
if(pthread_setschedparam(th.native_handle(), policy, &sch_params)) {
std::cerr << "Failed to set Thread scheduling : " << std::strerror(errno) << std::endl;
}
}
private:
sched_param sch_params;
};
and this is how I use it...
// create thread
std::thread example_thread(example_function);
// set scheduling of created thread
thread::setScheduling(example_thread, SCHED_RR, 2);
Solution 3 - C++
The standard C++ library doesn't define any access to thread priorities. To set thread attributes you'd use the std::thread
's native_handle()
and use it, e.g., on a POSIX system with pthread_getschedparam()
or pthread_setschedparam()
. I don't know if there are any proposals to add scheduling attributes to the thread interface.
Solution 4 - C++
In Windows processes are organized in class and level priority. Read this: Scheduling Priorities, it gives a good overall knowledge about thread and process priority. You can use the following functions to control the priorities even dynamically: GetPriorityClass(), SetPriorityClass(), SetThreadPriority(), GetThreadPriority().
Apperantly you can also use std::thread
's native_handle()
with pthread_getschedparam()
or pthread_setschedparam()
on a windows system. Check this example, std::thread: Native Handle and pay attention to the headers added!
Solution 5 - C++
You can use the following code to set the priorities in Windows
#if defined(_WIN32)
/* List of possible priority classes:
https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setpriorityclass
And respective thread priority numbers:
https://docs.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities
*/
DWORD dwPriorityClass = 0;
int nPriorityNumber = 0;
tasks::getWinPriorityParameters(setPriority, dwPriorityClass, nPriorityNumber);
int result = SetPriorityClass(
reinterpret_cast<HANDLE>(mainThread.native_handle()),
dwPriorityClass);
if(result != 0) {
std::cerr << "Setting priority class failed with " << GetLastError() << std::endl;
}
result = SetThreadPriority(
reinterpret_cast<HANDLE>(mainThread.native_handle()),
nPriorityNumber);
if(result != 0) {
std::cerr << "Setting priority number failed with " << GetLastError() << std::endl;
}
#endif
In our case, we had an abstraction layer to use the same code for both Windows and Linux task creation, so the tasks::getWinPriorityParameters
extracts the values expected from Windows from our setPriority
abstraction.