It is sometimes useful to get semi-realtime behavior from some of an application’s thread. This is common when I/O latency needs to be kept low, a good example being Software Defined Radio. The software component of the radio would like to read and write samples from the radio as soon as possible, keeping buffers small but also avoiding buffer overflows (on read) and underflows (on write).
A useful technique on Linux/Unix systems is changing threads’ scheduling priority. Linux supports several scheduling policies: SCHED_OTHER, the default scheduling policy, with round-robin sharing; SCHED_BATCH for batch processing; SCHED_IDLE for extremely low priority (background) jobs; and the two real-time priority policies SCHED_FIFO and SCHED_RR for FIFO and round-robin, respectively. In real-time scheduling policies, threads have a priority from 1 to 99, and higher priority threads always preempt lower priority threads. The order among waiting threads with the same priority is determined by the policy (FIFO or round-robin).
Two alternatives exist to set thread scheduling policy and priority: using chrt from the command line, and POSIX threads (also known as pthreads). For chrt, the chrt man page is a useful reference. Below are details and references for the use of pthreads.
The following code sets a thread’s real-time policy to SCHED_FIFO, with the maximum allowable priority. It uses the headers pthread.h and sched.h
#include <pthread.h> #include <sched.h>
We’ll set the priority of the current thread (via pthread_self), although it’s possible to set other threads’ priorities.
void set_realtime_priority() { int ret; // We'll operate on the currently running thread. pthread_t this_thread = pthread_self();
Setting thread priority is done through struct sched_param, which contains a sched_priority member. It’s possible to query the maximum and minimum priorities for a policy.
// struct sched_param is used to store the scheduling priority struct sched_param params; // We'll set the priority to the maximum. params.sched_priority = sched_get_priority_max(SCHED_FIFO);
Setting thread priority is one call to pthread_setschedparam.
std::cout << "Trying to set thread realtime prio = " << params.sched_priority << std::endl; // Attempt to set thread real-time priority to the SCHED_FIFO policy ret = pthread_setschedparam(this_thread, SCHED_FIFO, ¶ms); if (ret != 0) { // Print the error std::cout << "Unsuccessful in setting thread realtime prio" << std::endl; return; }
In some cases it makes sense to verify the thread priority and policy
// Now verify the change in thread priority int policy = 0; ret = pthread_getschedparam(this_thread, &policy, ¶ms); if (ret != 0) { std::cout << "Couldn't retrieve real-time scheduling paramers" << std::endl; return; } // Check the correct policy was applied if(policy != SCHED_FIFO) { std::cout << "Scheduling is NOT SCHED_FIFO!" << std::endl; } else { std::cout << "SCHED_FIFO OK" << std::endl; } // Print thread scheduling priority std::cout << "Thread priority is " << params.sched_priority << std::endl; }
Hope this snippet is useful. A more complete and involved demonstration (with a main) is available in the pthread_setschedparam man page. This stackoverflow question served as the starting point for this code.
It would be helpful if the code rendered with correct line wraps. Otherwise a helpful article.
Fixed. Sorry for that.
Thank you !
So this is called at the begging of the thread ?
Call it whenever you want to increase the thread’s priority.
I’ve modified some existing code to change to scheduling priority as you describe here in your post, but my software is unable to successfully set the realtime prio to 99. I’ve even trying executing the software as sudo as I thought it might be a permissions issue, but to no avail. How did you get you code to execute successfully as a normal, non-privileged user?
Happy you were able to find this. This has run on Linux as a privileged user, I’m not sure if I’ve tried it as a non-privileged user.
If you have tried it or resolved the issue, please report back with the result!
great work, thanks
Can the thread priority be changed for a running thread? I have found that I can set the priority before calling the create function but I need to change the priority for a running task and after some critical action I want to return to the previous priority; is there a way to do this ?