511遇见最近在录制易语言大漠从入门到提高,其中有几节涉及到多线程模板,为了使模板更加优化,录制的内容涉及到线程的优先级,和设置CPU亲和性,也就是线程和进程的cpu分配。涉及到两个api, SetProcessAffinityMask和SetThreadIdealProcessor
SetProcessAffinityMask
在多CPU的情况下,我们可以限制某些进程只在可用的cpu的一个子集上运行:(进程和CPU绑定)
下面是MSDN文档:
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setprocessaffinitymask
SetProcessAffinityMask 参数一:进程句柄 -1为自身句柄 参数二:指定CPU 参数二的设置是二进制转十进制。参数二需填写十进制数字 例如我想设置 1CPU二进制为1 转换为十进制为 1 2CPU二进制为10 转换为十进制为 2 3CPU二进制为100 转换为十进制为 4 4CPU二进制为1000 转换为十进制为 8 1,2CPU二进制为11 转换为十进制为 3 3,4CPU二进制为1100 转换为十进制为 12 123CPU二进制为1110 转换为十进制为 14 1234CPU二进制为1111 转换为十进制为 15
BOOL SetProcessAffinityMask( HANDLE hProcess, DWORD_PTR dwProcessAffinityMask);
获取进程的关联性掩码:
BOOL GetProcessAffinityMask( HANDLE hProcess, PDWORD_PTR pdwProcessAffinityMask, PDWORD_PTR pdwSystemAffinityMask);
设置线程的关联性掩码:
BOOL SetThreadAffinityMask( HANDLE hThread, DWORD_PTR dwThreadAffinityMask);
第一个参数hProcess代表要设置的进程。第二个参数dwProcessAffinityMask是一个位掩码,代表线程可以在哪些CPU上运行。例如,传入0x00000005意味着这个进程中的线程可以在CPU 0 和 CPU 2上运行,但是不能在CPU 1 和 CPU 3~31上运行。并不建议强制的分配,而是让进程创建时随机的分配。
问题思考
我们先获取cpu核心:cup.取核心数 ()
cpu是变量,类型是:类_cpu信息(精易模块)
我们开启多个游戏进程,我们想给每个游戏分配, SetProcessAffinityMask而实际测试,对外部进程的设置,返回失败,原因是,在进程创建时,就应当去执行分配:
假设你的游戏是:game.exe
系统_取DOS执行结果 (“start /affinity ” + 进制_十到十六 (进制_二到十(0001)) + “ ” + 游戏路径 + “\game.exe” )在第一个CPU上运行
系统_取DOS执行结果 (“start /affinity ” + 进制_十到十六 (进制_二到十(0010)) + “ ” + 游戏路径 + “\game.exe” )在第二个CPU上运行
系统_取DOS执行结果 (“start /affinity ” + 进制_十到十六 (进制_二到十(0011)) + “ ” + 游戏路径 + “\game.exe” )在第一个和第二个CPU上运行
SetProcessAffinityMask到底能不能设置外部进程,我们再做测试。
所以这个并不是让我们的辅助本身来分配,而是给我们多开的游戏来分配,下面SetThreadIdealProcessor是给我启动的线程来分配CPU核心,务必注意区别,也就是说,SetThreadIdealProcessor是用到启动线程后面的,
SetThreadIdealProcessor
要给线程设置一个理想的CPU,可以调用如下:
DWORD SetThreadIdealProcessor( HANDLE hThread, DWORD dwIdealProcessor);
hThread用于指明要为哪个线程设置首选CPU。
dwIdealProcessor函数不是个位掩码,它是个从0到31/63,用于指明供线程希望使用的首选CPU 。可以传递一个MAXIMUM_PROCESSORS的值(在WinNT.h中定义,在32位操作系统中定义为32,64位操作系统中定义为64),表明线程没有理想的CPU。如果没有为该线程设置理想的CPU,那么该函数返回前一个理想的CPU或MAXIMUM_PROCESSORS。
所以我们在易语言里当启动线程后,可以这样设置
如果真 (启动线程 (&脚本主线程, i, threadhwnd)) SetThreadIdealProcessor (threadhwnd, 64) ' 要看你的系统是多少位的。
这样让它自动给线程分配一个空闲的线程,从而避免线程的过度占用和堵塞。