场景
在编写音视频转换或者需要CPU密集型运算的应用时,一般会开启多线程进行并发执行,而多线程往往就会使用多个CPU. 这时候如果把CPU都用完了,CPU 使用率达到很高的话,就会影响电脑桌面的其他任务的执行,比如点击界面的软件,鼠标移动都会卡.
这时候如果只使用一半的CPU的话应该就不会影响用户的正常操作了.
- Win32 函数 SetProcessAffinityMask 就可以解决这个问题.
参考
用SetProcessAffinityMask为进程指定CPU
SetProcessAffinityMask function
Example usage of SetProcessAffinityMask in C/C++
例子
这个例子测试只使用第3,4的内核执行当前进程任务.
// test_cpu.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include <time.h>
#include <assert.h>
#include <iostream>
bool SetWorkProcessor(int n,...)
{
// On a system with more than 64 processors,
// the affinity mask must specify processors in a single processor group
assert(n < 64);
HANDLE process = GetCurrentProcess();
DWORD_PTR processAffinityMask;
DWORD_PTR systemAffinityMask;
if (!GetProcessAffinityMask(process, &processAffinityMask, &systemAffinityMask)) return false;
// 获取CPU个数
SYSTEM_INFO info;
::GetSystemInfo(&info);
// 设置处理器
va_list argptr;
va_start(argptr, n);
int result = 0;
for(int i = 0;i<n;++i)
{
int value = va_arg(argptr, int);
if(value < info.dwNumberOfProcessors)
{
result |= (1 << value);
}
}
va_end(argptr);
if(result)
{
return SetProcessAffinityMask(process,result);
}
return false;
}
DWORD WINAPI ThreadFunc(PVOID pvParam)
{
int i = 0;
while(true)
{
++i;
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
// 设置使用的CPU
assert(SetWorkProcessor(2,2,3));
DWORD dwThreadID;
for(int i = 0; i < 10; ++i)
{
CreateThread(NULL,0,ThreadFunc,NULL,0,&dwThreadID);
}
int i = 0;
while(true)
{
++i;
}
return 0;
}
图1 未执行程序前,3,4 CPU使用率并不高
图2 执行程序后,3,4 CPU使用率暴涨,但是1,2 CPU没怎么变化.
图3 不设置CPU处理函数,看4个CPU使用率吓人.