Setting thread priority in Linux with Boost
That's the basic template for how I would do it but after searching around I found next to no code examples so I guess the verdict is out on whether it is best or not.
The problem is that boost::thread does not have a constructor that allows pthead attributes to be passed in at thread creation so you have to make changes after the thread starts. The only other way I know to get around that is through the process/thread schedule inheritance. Unless directed otherwise, new threads will inherit the schedule/priority of their creator so you could change the current thread before creating worker threads and then change back if you want. Seems awkward but it is an alternative.
Here's a hack of an example that hopefully demostrates both. You may need to change policy and priority as appropriate and run as root.
Be careful with the way you set the priority. Various restrictions apply.
#include <iostream>
#include <boost/thread/thread.hpp>
#include <unistd.h>
#include <sched.h>
#include <cstdio>
void* threadfunc()
{
sleep(5);
}
void displayAndChange(boost::thread& daThread)
{
int retcode;
int policy;
pthread_t threadID = (pthread_t) daThread.native_handle();
struct sched_param param;
if ((retcode = pthread_getschedparam(threadID, &policy, ¶m)) != 0)
{
errno = retcode;
perror("pthread_getschedparam");
exit(EXIT_FAILURE);
}
std::cout << "INHERITED: ";
std::cout << "policy=" << ((policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???")
<< ", priority=" << param.sched_priority << std::endl;
policy = SCHED_FIFO;
param.sched_priority = 4;
if ((retcode = pthread_setschedparam(threadID, policy, ¶m)) != 0)
{
errno = retcode;
perror("pthread_setschedparam");
exit(EXIT_FAILURE);
}
std::cout << " CHANGED: ";
std::cout << "policy=" << ((policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???")
<< ", priority=" << param.sched_priority << std::endl;
}
int main(int argc, char* argv[])
{
int policy, res;
struct sched_param param;
if ((policy = sched_getscheduler(getpid())) == -1)
{
perror("sched_getscheduler");
exit(EXIT_FAILURE);
}
if ((res = sched_getparam(getpid(), ¶m)) == -1)
{
perror("sched_getparam");
exit(EXIT_FAILURE);
}
std::cout << " ORIGINAL: ";
std::cout << "policy=" << ((policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???")
<< ", priority=" << param.sched_priority << std::endl;
policy = SCHED_RR;
param.sched_priority = 2;
if ((res = sched_setscheduler(getpid(), policy, ¶m)) == -1)
{
perror("sched_setscheduler");
exit(EXIT_FAILURE);
}
boost::thread t1(&threadfunc);
displayAndChange(t1);
t1.join();
return 0;
}
C++ & boost::threads - How to prioritize thread based on work type?
As far as I know boost doesn't provide an API to do it (the C++11 standard certainly doesn't at least).
On Linux, you can nice
or setpriority
each thread independently from the others. Note however that this is not POSIX-conformant:
According to POSIX, the nice value is a per-process setting. However, under the current Linux/NPTL implementation of POSIX threads, the nice value is a per-thread attribute: different threads in the same process can have different nice values. Portable applications should avoid relying on the Linux behavior, which may be made standards conformant in the future.
Since Linux uses pthreads
(and so does the Linux port of boost
) you could also use pthread_setschedparam
which has the advantage of being more portable than the Linux-specific per-thread nice
behaviour.
In both cases, there's the slight uneasiness due to having to resort to system facilities in order to manage supposedly "opaque" boost
(or std
in C++11) resources, so tread carefully (as with anything implementation-specific).
Performance/priority in Boost thread with accept() (Linux)
if you or the class you use is doing an accept
call, then the thread is blocked and is waiting for the OS to do some things. SO the thread is (should) not be consuming any CPU ressources, if it does so, it is either
- within the system call (nothing you could change) or
- there is a time-out and the thread is looping to
accept
again. If
there is any parameter to change this, try it!
Boost: how to set program priority?
There's no generalised cross-platform priority support in boost itself.
#ifdef
is your friend...
See Tom's answer for the win32 solution.
On Linux you'd use the nice
call (or possibly setpriority
). Don't be put off by those document's statements that they adjust process priority; on Linux a thread is just a process which shares a memory space with some other process/processes. If you get yourself a better version of "top" which lists the individual threads, you can see the nice levels of each.
Note that a process/thread with normal user privileges can only reduce its priority (higher "nice" value) on Linux. The little bit of work with priorities I've done on Windows, it seemed anything goes (but that was on XP; situation may be different post-Vista, UAC etc).
Set a higher priority to a boost::asio thread wrt the process
I'm with the commenters that doubt this will be useful.
But to answer your question: there is no such thing as a Boost Asio thread.
It is explicitly documented why:
Threads And Boost Asio
Consequently, it is the library user's responsibility to create and
manage all threads to which the notifications will be delivered.The reasons for this approach include:
- By only calling
io_context::run()
from a single thread, the user's code can avoid the development complexity associated with
synchronisation. For example, a library user can implement scalable
servers that are single-threaded (from the user's point of view).- A library user may need to perform initialisation in a thread shortly after the thread starts and before any other application code
is executed. For example, users of Microsoft's COM must call
CoInitializeEx
before any other COM operations can be called from that
thread.- The library interface is decoupled from interfaces for thread creation and management, and permits implementations on platforms
where threads are not available.
So, you create your own threads - except the main thread I suppose - and can do so in whatever fashion you require.
Equivalent of SetThreadPriority on Linux (pthreads)
The equivalent to SetThreadPriority
in linux would be pthread_setschedprio(pthread_t thread, int priority)
.
Check the man page.
EDIT: here's the sample code equivalent:
#include <pthread.h>
int main()
{
pthread_t thId = pthread_self();
pthread_attr_t thAttr;
int policy = 0;
int max_prio_for_policy = 0;
pthread_attr_init(&thAttr);
pthread_attr_getschedpolicy(&thAttr, &policy);
max_prio_for_policy = sched_get_priority_max(policy);
pthread_setschedprio(thId, max_prio_for_policy);
pthread_attr_destroy(&thAttr);
return 0;
}
This sample is for the default scheduling policy which is SCHED_OTHER.
EDIT: thread attribute must be initialized before usage.
Related Topics
Is Shrink_To_Fit the Proper Way of Reducing the Capacity a 'Std::Vector' to Its Size
What Is Void* and to What Variables/Objects It Can Point To
Preventing Non-Const Lvalues from Resolving to Rvalue Reference Instead of Const Lvalue Reference
How to Asynchronously Copy Memory from the Host to the Device Using Thrust and Cuda Streams
How to Install Llvm Toolchain for Eclipse Cdt
Understand Op Registration and Kernel Linking in Tensorflow
Why Does Initializing an Extern Variable Inside a Function Give an Error
C++ Template Instantiation: Avoiding Long Switches
Portability of Native C++ Properties
C++ Inheritance via Dominance Warning
Std::Unordered_Map::Find Using a Type Different Than the Key Type
Understanding the Different Clocks of Clock_Gettime()
Amortized Analysis of Std::Vector Insertion
How to Be Notified of File/Directory Change in C/C++, Ideally Using Posix
How to Define Template Function Within Template Class in *.Inl File