查询线程(不是进程)处理器关联?

Dan*_*Dan 5 windows winapi multithreading

在Windows上,您可以为进程调用SetProcessAffinityMask,为线程调用SetThreadAffinityMask.但是,Windows似乎只显示GetProcessAffinityMask而不是流程的各个线程的类似API.

我有一个多线程程序,可以在运行时将各个线程绑定到处理器.当我运行它时,我想(外部)查询哪些线程正在哪些处理器上运行,以确保它正常工作.我写了一个小的命令行实用程序来执行此操作.但我似乎无法找到一种方法来查找单个线程绑定的处理器或核心.

这显然必须是可能的; 我在网上看到了adplus调试实用程序的描述,它能够显示类似pstack的输出以显示线程关联.Process Explorer在多处理器计算机上显示一个Threads选项卡,显示线程的"Ideal Processor".

有谁知道如何查询这条信息?

Dam*_*mon 6

您可以通过两次调用来完成SetThreadAffinityMask.此函数返回传递的线程句柄的原始关联掩码.

所以...使用掩码进行一次调用,该掩码设置与一个CPU的亲和性,然后再进行一次调用以恢复原始掩码.

这是完整的C/C++源代码,包括错误检查:

DWORD GetThreadAffinityMask(HANDLE thread)
{
    DWORD mask = 1;
    DWORD old = 0;

    // try every CPU one by one until one works or none are left
    while(mask)
    {
        old = SetThreadAffinityMask(thread, mask);
        if(old)
        {   // this one worked
            SetThreadAffinityMask(thread, old); // restore original
            return old;
        }
        else
        {
            if(GetLastError() != ERROR_INVALID_PARAMETER)
                return 0; // fatal error, might as well throw an exception
        }
        mask <<= 1;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此代码一次探测一个CPU,直到设置关联性工作(在这种情况下,我们现在知道原始掩码!)或直到初始化1已移出DWORD.如果询问CPU不可用,则该功能失败ERROR_INVALID_PARAMETER,我们只需尝试下一个.通常第一个CPU才能正常工作,因此效率相当高.

如果函数失败ERROR_INVALID_PARAMETER,则表示我们要么对句柄没有足够的访问权限,要么系统遇到一些实际问题,因为它无法满足我们的请求.因此,在这种情况下继续没有意义.


wj3*_*j32 6

呼叫NtQueryInformationThread,与ThreadBasicInformation:

typedef struct _THREAD_BASIC_INFORMATION
{
    NTSTATUS ExitStatus;
    PTEB TebBaseAddress;
    CLIENT_ID ClientId;
    ULONG_PTR AffinityMask;
    KPRIORITY Priority;
    LONG BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
Run Code Online (Sandbox Code Playgroud)

AFAIK没有记录获得线程亲和力的方法.