设置std::threads的线程亲和性

3

我正在尝试通过win32 API设置std::thread或boost::thread的线程亲和性。我想使用SetThreadAffinityMask函数将每个线程固定到我的机器上的特定核心。

我使用了线程native_handle成员函数获取传递给SetThreadAffinityMask函数的线程句柄。然而,这样做导致SetThreadAffinityMask函数返回0,表示无法设置线程亲和性。

unsigned numCores = std::thread::hardware_concurrency();
std::vector<std::thread> threads(numCores);

for (int i = 0; i < numCores; i++)
{
    threads.push_back(std::thread(workLoad, i));
    cout << "Original Thread Affinity Mask: " << SetThreadAffinityMask(threads[i].native_handle() , 1 << i) << endl;

}

for (thread& t : threads)
{
    if (t.joinable())
        t.join();
}

原始线程亲和掩码: 0

原始线程亲和掩码: 0

原始线程亲和掩码: 0

原始线程亲和掩码: 0

原始线程亲和掩码: 0

原始线程亲和掩码: 0

原始线程亲和掩码: 0

...等等


GetLastError() 返回什么错误代码? - Jonathan Potter
这只是我之前测试时的旧代码,不用理会那个可加入的循环。 - Joe Schmoe
@JonathanPotter 错误代码6...无效的句柄。 - Joe Schmoe
@JoeSchmoe -- 哎呀,我刚刚删除了我的评论,因为正如答案所指出的那样,这个向量确实有一堆无法连接的线程。<g> - Pete Becker
1个回答

3
你的问题在于初始设置 threads 包含了 numCores 默认初始化的条目。你的新线程被推入向量后,但在设置关联性时从未对它们进行索引。相反,你使用 i 进行索引,这只是命中了向量中那些不是真正运行的线程对象之前的对象。
下面是一个已修正的可运行版本:
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>

#include <windows.h>

void proc(void)
{
    using namespace std::chrono_literals;
    std::this_thread::sleep_for(5s);
}

int main()
{
    std::vector<std::thread> threads;
    for (unsigned int i = 0; i < std::thread::hardware_concurrency(); ++i)
    {
        threads.emplace_back(proc);
        DWORD_PTR dw = SetThreadAffinityMask(threads.back().native_handle(), DWORD_PTR(1) << i);
        if (dw == 0)
        {
            DWORD dwErr = GetLastError();
            std::cerr << "SetThreadAffinityMask failed, GLE=" << dwErr << '\n';
        }
    }

    for (auto& t : threads)
        t.join();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接