进程和线程的亲缘性(affinity)是指可以将进程或者是线程强制限制在可用的CPU子集上运行的特性,它一定程度上把进程/线程在多处理器系统上的调度策略暴露给系统程序员,有助于程序员实现自己的调度策略以提供特定情况下的更好性能。
默认情况下,Windows Vista(2000以上系统)使用“soft affinity”(软亲缘性)的操作将线程分配给CPU。这意味着如果其他因素不变,系统运行线程的时候设法在该线程上次运行的那个CPU上运行该线程,以此重复使用仍然保存在CPU的cache中的数据。与“soft affinity”相对的是“hard affiinty”(硬亲缘性),使用它可以控制哪个CPU运行哪些线程。请注意,子进程可以继承进程的亲缘性。
为此windows提供了设置进程亲缘性的函数:SetProcessAffinityMask。 当然,还有一个函数能够返回进程的亲缘性位屏蔽,它就是:GetProcessAffinityMask。有时你可能想要将进程中的一个线程限制到一组CPU上去运行。可以通过调用SetThreadAffinityMask,你就能为各个线程设置亲缘性屏蔽。
BOOL SetProcessAffinityMask(
HANDLE hProcess,
DWORD_PTR dwProcessAffinityMask);
该函数的第一个参数指明了要被限制的进程,第二个参数是一个“位屏蔽”数据,里面的每个位表示一个CPU代号(从0开始标号),比如 0x00000001表示选中CPU 0,也就是“该进程中的线程”只能运行在CPU 0上了;0x00000005表示同时选中CPU 0和CPU 2。
BOOL GetProcessAffinityMask(
HANDLE hProcess,
PDWORD_PTR pdwProcessAffinityMask,
PDWORD_PTR pdwSystemAffinityMask);
该函数通过第二个参数返回指定进程的CPU的亲缘性信息,同时可以通过第三个参数返回系统亲缘性信息。系统亲缘性指明系统的哪些CPU可以处理线程,进程的亲缘性始终是系统亲缘性的子集。
DWORD_PTR SetThreadAffinityMask(
HANDLE hThread,
DWORD_PTR dwThreadAffinityMask);
该函数的第二个参数的意义和SetProcessAffinityMask函数中的第二个参数相同。也必须指明了一个正确的CPU子集,限制指定的线程只能运行在这个CPU子集上。该函数返回原来的线程的亲缘信息。