Portable way of setting std::thread priority in C++11

64,806

Solution 1

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

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

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

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!

Share:
64,806
Gerdiner
Author by

Gerdiner

Updated on July 23, 2021

Comments

  • Gerdiner
    Gerdiner almost 3 years

    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?

  • Antiokus
    Antiokus about 8 years
    actually @MarkusMayr this was pretty useful in showing a real implementation. the other answers just referred the functions but never showed a proper example. It might not be idiomatic, but I believe it demonstrates the concept of setting a priority for a particular thread. At the very least - it helped me.
  • Pete Becker
    Pete Becker about 8 years
    Note, however, that this code relies on implementation-specific behavior by calling native_handle(); the standard does not require that function to exist, and if it does, the standard does not require it to have any particular meaning. Everything about it except its name is implementation defined.
  • Mahler
    Mahler almost 5 years
    This answer is more accurate than others.
  • zertyz
    zertyz over 4 years
  • Deduplicator
    Deduplicator almost 3 years
    @PeteBecker Not surprising at all, as it is all about breaking into and using the native interface abstracted as possible by std::thread.
  • Pete Becker
    Pete Becker almost 3 years
    @Deduplicator -- but it is surprising that the standard reserves that name with no semantics whatsoever. Unfortunately, I couldn't convince the committee that the right way to do that is to do nothing, and leave it to the implementation to provide implementation-specific behavior.
  • Deduplicator
    Deduplicator almost 3 years
    @PeteBecker They had to provide some standard way for getting a hand on the underlying thread, or everybody and their dog would choose their own, incidentally tainting the space for future development. They couldn't give it any more constraints than they did, because that would either limit conforming platforms, or necessitate building yet another abstraction just for this, which would need its own escape hatch, and that additional indirection wouldn't buy you anything really.
  • Pete Becker
    Pete Becker almost 3 years
    @Deduplicator -- there's no portable code that you can write that uses this function; you can't even call it in portable code, because it doesn't have to exist. There's nothing at all that's more clearly implementation-specific than that. Using an implementation-specific name would point out that code that uses it is not portable.
  • Deduplicator
    Deduplicator almost 3 years
    @PeteBecker The point is that portable code (for example templates detecting existence and maybe ability to invoke) won't be inconvenienced, nor will future development by rogue symbols. Also, especially as this escape-hatch is shared across other classes, it is a well-known pattern and eases search for that platform-specific code, or proving its absence.
  • Pete Becker
    Pete Becker almost 3 years
    Um, future readers of code that calls native_handle() don't have any indication that what's done after that call is not portable. Leaving it to implementors to use a name from the implementer's namespace flags that there is something here to watch out for. Even folks on the committee have made the mistake of assuming that they knew what they could do with the handle that they got back, but discovered, when they successfully compiled their code with a different library implemenation, that they were wrong.