windows 查询线程(不是进程)处理器亲和性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6601862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 17:18:47  来源:igfitidea点击:

Query thread (not process) processor affinity?

windowsmultithreadingwinapi

提问by Dan

On Windows, you can call SetProcessAffinityMask for a process and SetThreadAffinityMask for a thread. However, Windows only appears to expose GetProcessAffinityMask and not a similar API for individual threads of a process.

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

I have a multi-threaded program that binds individual threads to processors at run-time. As I run it, I'd like to (externally) query which threads are running on which processors to make sure it's working correctly. I've written a small command-line utility to do this. But I can't seem to find a means of finding which processor(s) or core(s) an individual thread is bound to.

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

This apparently must be possible; I've seen descriptions online of the adplus debugging utility being able to show pstack-like output to show thread affinity. And Process Explorer shows a Threads tab on multi-processor machines that shows the "Ideal Processor" of a thread.

这显然是可能的;我在网上看到过关于能够显示类似 pstack 的输出以显示线程关联性的 adplus 调试实用程序的描述。进程资源管理器在多处理器机器上显示一个线程选项卡,显示线程的“理想处理器”。

Does anyone know how to query this piece of information?

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

回答by Damon

You can do it with two calls to SetThreadAffinityMask. This function returns the original affinity maskfor the passed thread handle.

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

So... do one call with a mask that sets affinity to one CPU, and then do a second call to restore the original mask.

所以...使用设置了一个 CPU 的关联性的掩码进行一次调用,然后进行第二次调用以恢复原始掩码。

Here is complete C/C++ source code including error checking:

这是完整的 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;
}

This code probes one CPU at a time, until setting affinity works (in this case we now know the original mask!) or until the initial 1has been shifted out of the DWORD. If a CPU is asked that is not available, the function fails with ERROR_INVALID_PARAMETER, and we just try the next one. Usually the first CPU will just work, so it's reasonably efficient.

此代码一次探测一个 CPU,直到设置亲和性起作用(在这种情况下我们现在知道原始掩码!)或直到初始值1已移出DWORD. 如果询问某个 CPU 不可用,该函数将失败并显示ERROR_INVALID_PARAMETER,我们只尝试下一个。通常第一个 CPU 会正常工作,因此它的效率相当高。

If the function fails with anything other than ERROR_INVALID_PARAMETER, it means that we either don't have sufficient access rights to the handle, or the system is having some real problems because it can't fulfill our request. Therefore it doesn't make sense to continue in this case.

如果该函数因除 之外的任何原因而失败ERROR_INVALID_PARAMETER,则意味着我们对句柄没有足够的访问权限,或者系统存在一些实际问题,因为它无法满足我们的请求。因此,在这种情况下继续下去是没有意义的。

回答by wj32

Call NtQueryInformationThread, with ThreadBasicInformation:

呼叫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;

AFAIK there's no documented way of getting the thread affinity.

AFAIK 没有记录的获取线程关联的方法。

回答by que dal

a faster way is to call GetCurrentProcessorNumbersee msdnwhich will return the number of the processor the current thread was running on during the call to this function.

更快的方法是调用GetCurrentProcessorNumbersee msdn,它将返回在调用此函数期间当前线程正在运行的处理器的编号。

c# code :

代码:

/// <summary>
/// Retrieves the number of the processor the current thread was running on <para/>
/// during the call to this function.
/// </summary>
/// <returns>The function returns the current processor number.</returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern int GetCurrentProcessorNumber();