“hard affiinty”(硬亲缘性),使用它可以控制哪个CPU运行哪些线程。
SetProcessAffinityMask函数限制一个特定的进程只能运行在CPU的一个子集上。
BOOL SetProcessAffinityMask(
HANDLE hProcess,
DWORD_PTR dwProcessAffinityMask);
该函数得第一个参数指明了要被限制的进程,第二个参数是一个“位屏蔽”数据,里面的每个位表示一个CPU代号(从0开始标号),比如0x00000001表示选中CPU 0,也就是“该进程中的线程”只能运行在CPU 0上了;0x00000005表示同时选中CPU 0和CPU 2。
一个进程中的子进程可以继承该进程的亲缘性,也可以使用作业内核对象对某些进程限制在要求的一组CPU上执行。
可以调用GetProcessAffinityMask函数来取得一个进程亲缘性屏蔽信息。
BOOL GetProcessAffinityMask(
HANDLE hProcess,
PDWORD_PTR pdwProcessAffinityMask,
PDWORD_PTR pdwSystemAffinityMask);
该函数通过第二个参数返回指定进程的CPU的亲缘性信息,同时可以通过第三个参数返回系统亲缘性信息。系统亲缘性指明系统的哪些CPU可以处理线程,进程的亲缘性始终是系统亲缘性的子集。
以上讨论的是如何把一个进程中的所有线程限制在一组CPU上。有的时候想要把进程的一个具体线程限制在一组CPU上。
SetThreadAffinityMask函数可以限制某一个线程只能运行在一组CPU上。
DWORD_PTR SetThreadAffinityMask(
HANDLE hThread,
DWORD_PTR dwThreadAffinityMask);
该函数的第二个参数的意义和SetProcessAffinityMask函数中的第二个参数相同。也必须指明了一个正确的CPU子集,限制指定的线程只能运行在这个CPU子集上。该函数返回原来的线程的亲缘信息。
比如,现在有4个线程和4个可用的CPU,你想让线程1独占CPU 0,让其他3个线程只能运行在CPU 1、CPU 2、CPU 3上,可以如下编码:
SetThreadAffinityMask(hThread0, 0x00000001);
SetThreadAffinityMask(hThread1, 0x0000000E);
SetThreadAffinityMask(hThread2, 0x0000000E);
SetThreadAffinityMask(hThread3, 0x0000000E);