在 C + + 11中设置 std: : 线程优先级的可移植方法

在后 C + + 11的世界中,设置 std: : thread 实例的优先级的正确方法是什么

是否有一种至少在 Windows 和 POSIX (Linux)环境中可以实现的便携式方法?

或者是获得一个句柄并使用特定操作系统可用的任何本机调用的问题?

73301 次浏览

标准的 C + + 库没有定义任何对线程优先级的访问。要设置线程属性,您需要使用 std::threadnative_handle()并使用它,例如,在具有 pthread_getschedparam()pthread_setschedparam()的 POSIX 系统上。我不知道是否有向线程接口添加调度属性的建议。

没有办法通过 C + + 11库设置线程优先级。我不认为这会在 C + + 14中改变,我的水晶球太模糊以至于不能评论之后的版本。

在 POSIX

Win32 BOOL SetThreadPriority(HANDLE hThread,int nPriority)

在 Windows 中,进程按类和级别优先级组织。阅读以下内容: 计划优先级,它提供了关于线程和进程优先级的全面知识。您可以使用以下函数来动态控制优先级: GetPriorityClass ()SetPriorityClass ()设置线程优先级()获取线程优先级()

显然,你也可以在 Windows 系统上使用 std::threadnative_handle()pthread_getschedparam()pthread_setschedparam()。检查这个例子,Thread: 本机句柄和注意的标题添加!

我的快速执行..。

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

我就是这么用的。

// create thread
std::thread example_thread(example_function);


// set scheduling of created thread
thread::setScheduling(example_thread, SCHED_RR, 2);

可以使用下面的代码设置 Windows 中的优先级

#if defined(_WIN32)
/* List of possible priority classes:
https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setpriorityclass
And respective thread priority numbers:
https://learn.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

在我们的例子中,我们有一个抽象层来使用相同的代码来创建 Windows 和 Linux 任务,所以 tasks::getWinPriorityParameters从我们的 setPriority抽象中提取出了 Windows 的预期值。

为了降低当前线程的优先级,我使用:

namespace
{
#ifdef WIN32
auto lower_my_priority() -> bool
{
int priority { GetThreadPriority(GetCurrentThread()) };
return priority != THREAD_PRIORITY_ERROR_RETURN
&& priority > THREAD_PRIORITY_IDLE
&& SetThreadPriority(
GetCurrentThread(),
priority > THREAD_PRIORITY_HIGHEST
? THREAD_PRIORITY_HIGHEST
: priority > THREAD_PRIORITY_ABOVE_NORMAL
? THREAD_PRIORITY_ABOVE_NORMAL
: priority > THREAD_PRIORITY_NORMAL
? THREAD_PRIORITY_NORMAL
: priority > THREAD_PRIORITY_BELOW_NORMAL
? THREAD_PRIORITY_BELOW_NORMAL
: priority > THREAD_PRIORITY_LOWEST
? THREAD_PRIORITY_LOWEST
: THREAD_PRIORITY_IDLE)
!= 0;
}
#else
auto lower_my_priority() -> bool
{
int policy;
sched_param params;
if (pthread_getschedparam(
pthread_self(), &policy, &params) == 0)
{
int const min_value{ sched_get_priority_min(policy) };
if (min_value != -1)
{
if (params.sched_priority > min_value)
{
--params.sched_priority;
if (pthread_setschedparam(pthread_self(), policy, &params) != -1)
{
return true;
}
}
}
}


return false;
}
#endif
}

当然,您可以编写提高优先级的等效代码