【发布时间】:2018-05-19 20:12:23
【问题描述】:
在Qt5中使用线程,如何设置单个线程的CPU affinity?
我想指定线程可能在其下运行的可用 CPU 内核的掩码。
换句话说,什么是 Qt5 等价于 Posix 线程的 pthread_setaffinity_np() ?
我可以对QThreadPool 管理的线程执行此操作吗?
【问题讨论】:
标签: c++ multithreading qt qt5 affinity
在Qt5中使用线程,如何设置单个线程的CPU affinity?
我想指定线程可能在其下运行的可用 CPU 内核的掩码。
换句话说,什么是 Qt5 等价于 Posix 线程的 pthread_setaffinity_np() ?
我可以对QThreadPool 管理的线程执行此操作吗?
【问题讨论】:
标签: c++ multithreading qt qt5 affinity
通常这类事情是通过提取本机线程句柄然后执行任何必要的系统特定工作来完成的,因为不存在用于低级线程管理的公认跨平台 API。
确实,如果我们检查qthread_unix.cpp 的来源,我们将看到以下内容:
Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
{
// requires a C cast here otherwise we run into trouble on AIX
return to_HANDLE(pthread_self());
}
在qthread_win.cpp 中,实现方式将与预期不同:
Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
{
return reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId()));
}
因此,应用程序代码有责任针对预期运行的每个平台执行适当的低级操作。
【讨论】:
Qt 不提供任何用于设置处理器关联的公共 API。对于QThreadPool,绝对没有办法做到这一点,它甚至不提供用于访问池中QThreads 的API。
对于显式创建的QThread 对象,您可以尝试使用QThread::getCurrentThreadId() 函数将本机“句柄”返回给线程,然后将其传递给系统的线程管理库调用。但我强烈建议不要这样做。文档明确指出:
警告:此函数返回的句柄用于内部用途,不应在任何应用程序代码中使用。
如果您正在为特定平台构建,您可能可以混合调用您的操作系统库(例如,pthreads),但这将无法移植,我不知道它是否可以工作。
您最好的选择可能是从命令行管理整个应用程序的 CPU 亲和性。如果您使用的是 Linux,taskset 是您的最佳选择。对于 Windows,请查看 this SO answer。不幸的是,Apple 似乎非常坚决地阻止用户设置线程亲和性,至少在命令行中是这样。
【讨论】: