如何判断指定进程内不同线程是否在不同核心上真正并行运行?
如何判断进程内线程是否在不同核心并行运行
我完全懂你的需求——GetProcessAffinityMask只能告诉你进程被允许在哪些CPU核心上运行,但没法精准追踪单个线程当前实际在哪个核心执行,要确认线程是否真的处于并行状态,得拿到每个线程的实时运行核心信息才行。下面分平台给你具体方案:
Windows平台
1. 获取线程允许运行的核心范围
如果只是想知道线程有没有被限制在特定核心,可以用GetThreadAffinityMask函数,它返回的是线程的亲和性掩码(比进程级的粒度更细):
DWORD_PTR threadAffinityMask; DWORD_PTR processAffinityMask; if (GetThreadAffinityMask(hThread, &threadAffinityMask, &processAffinityMask)) { // threadAffinityMask 就是线程允许运行的核心掩码 }
不过这只是允许的范围,不是当前实际运行的核心。
2. 获取线程当前运行的核心编号
要拿到线程当前正在执行的CPU核心,得用到Windows的Native API NtQueryInformationThread,指定ThreadQueryProcessorId查询类别。因为这个API不属于公开的Win32头文件,需要自己声明相关结构体和函数:
#include <windows.h> typedef struct _THREAD_PROCESSOR_ID_INFORMATION { ULONG ProcessorId; } THREAD_PROCESSOR_ID_INFORMATION, *PTHREAD_PROCESSOR_ID_INFORMATION; typedef NTSTATUS(WINAPI* PNtQueryInformationThread)( HANDLE ThreadHandle, ULONG ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength ); // 加载ntdll.dll并获取函数地址 PNtQueryInformationThread NtQueryInformationThread = (PNtQueryInformationThread)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryInformationThread"); // 调用获取线程当前CPU编号 THREAD_PROCESSOR_ID_INFORMATION info; ULONG returnLen; NTSTATUS status = NtQueryInformationThread( hThread, 0x18, // ThreadQueryProcessorId 的对应值为0x18 &info, sizeof(info), &returnLen ); if (status == 0) { // info.ProcessorId 就是当前线程运行的核心编号(从0开始计数) }
注意:这个方法获取的是瞬时值,线程可能随时被调度器切换核心,建议多次采样来确认是否持续在不同核心并行。
Linux平台
1. 读取/proc文件系统
Linux的/proc伪文件系统提供了所有进程和线程的详细运行信息,要获取某个线程的当前运行核心,直接读取/proc/[pid]/task/[tid]/stat文件,其中第39个字段(从1开始计数)就是当前CPU编号:
比如用命令行快速查看:
cat /proc/1234/task/5678/stat | awk '{print $39}'
在代码里可以通过打开这个文件、解析对应字段来实现。
2. 线程自身获取当前核心
如果是线程自己想知道当前运行的核心,直接调用sched_getcpu()函数即可:
#include <sched.h> int cpu = sched_getcpu(); // cpu 就是当前核心编号(从0开始计数)
确认并行的关键点
- 首先确保进程的亲和性掩码包含多个核心(用
GetProcessAffinityMask或sched_getaffinity确认),否则线程根本没机会并行。 - 多次采样线程的当前运行核心,如果两个线程在多数采样点都处于不同核心,且线程状态为
R(运行中),那就能确认它们是真正并行运行的。
内容的提问来源于stack exchange,提问作者Generic Name
相关产品推荐
相关产品推荐

