问题描述
如何使用SetProcessAffinityMask选择多个逻辑处理器?
How can I use SetProcessAffinityMask to select more than one logical processor?
在Windows任务管理器中,您可以这样做:
In Windows Task Manager you can do this as an example:
我更新了我的过程来执行此操作:
I updated my CreateProcess procedure to do this:
type
TProcessPriority = (ptLow = $00000040,
ptBelowNormal = $00004000,
ptNormal = $00000020,
ptAboveNormal = $00008000,
ptHigh = $00000080,
ptRealtime = $00000100);
procedure RunProcess(FileName: string; Priority: TProcessPriority);
var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
CmdLine: string;
Done: Boolean;
begin
FillChar(StartInfo, SizeOf(TStartupInfo), #0);
FillChar(ProcInfo, SizeOf(TProcessInformation), #0);
StartInfo.cb := SizeOf(TStartupInfo);
CmdLine := FileName;
UniqueString(CmdLine);
try
Done := CreateProcess(nil, PChar(CmdLine), nil, nil, False,
CREATE_NEW_PROCESS_GROUP + Integer(Priority),
nil, nil, StartInfo, ProcInfo);
if Done then
begin
// Todo: Get actual cpu core count before attempting to set affinity!
// 0 = <All Processors>
// 1 = CPU 0
// 2 = CPU 1
// 3 = CPU 2
// 4 = CPU 3
// 5 = CPU 5
// 6 = CPU 6
// 7 = CPU 6
// 8 = CPU 7
// this sets to CPU 0 - but how to allow multiple parameters to
// set more than one logical processor?
SetProcessAffinityMask(ProcInfo.hProcess, 1);
end else
MessageDlg('Could not run ' + FileName, mtError, [mbOk], 0)
finally
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;
end;
注意我在那里发表的评论。更新我的程序,以包括一个新的Affinity参数,我可以传递给SetProcessAffinityMask。
Note the comments I put in there. It would be good to update my procedure to include a new Affinity parameter which I can pass to SetProcessAffinityMask.
调用其中任何一个将不会因为明显的原因选择相应的处理器,他们给出了我想做什么的想法:
Calling any of these won't select the corresponding processors for obvious reasons, they give the idea of what I am wanting to do:
SetProcessAffinityMask(ProcInfo.hProcess, 1 + 2);
SetProcessAffinityMask(ProcInfo.hProcess, 1 and 2);
例如,为进程选择任何CPU,如任务管理器中所示。
eg, select any of the CPU's for a process, as shown in Task Manager.
我该怎么做,使用数组,集合或其他东西?我不能让它处理多个值。
How should I do this, using an Array, Set or something else? I cannot get it to work with multiple values.
谢谢。
推荐答案
p>它是按照所述的位掩码。
It is a bitmask as described in the documentation.
- 处理器0为$ 01。
- 处理器1为$ 02。 >
- 处理器2为$ 04。
- 处理器3为$ 08。
- 处理器4为$ 10。
- Processor 0 is $01.
- Processor 1 is $02.
- Processor 2 is $04.
- Processor 3 is $08.
- Processor 4 is $10.
等等。您可以使用逻辑或
组合它们。因此,处理器0和1将是 $ 01
或 $ 02
等于 $ 03
。
And so on. You can use logical or
to combine them. So processors 0 and 1 would be $01
or $02
which equals $03
.
我将使用移位运算符 shl
为特定处理器创建值。如下:
I would use the shift operator shl
to create values for specific processors. Like this:
function SingleProcessorMask(const ProcessorIndex: Integer): DWORD_PTR;
begin
Result := 1 shl (ProcessorIndex-1);
end;
您可以轻松地将其扩展为使用逻辑或$>
You can readily extend this to generate masks for lists of processors using logical or
in a loop.
function CombinedProcessorMask(const Processors: array of Integer): DWORD_PTR;
var
i: Integer;
begin
Result := 0;
for i := low(Processors) to high(Processors) do
Result := Result or SingleProcessorMask(Processors[i]);
end;
您可以测试像这样的位掩码中的处理器:
You can test for a processor being in a bit mask like this:
function ProcessorInMask(const ProcessorMask: DWORD_PTR;
const ProcessorIndex: Integer): Boolean;
begin
Result := (SingleProcessorMask(ProcessorIndex) and ProcessorMask)<>0;
end;
注意:我正在使用 DWORD_PTR
因为64位目标,位掩码是64位宽。这个细微差别对于XE来说并不重要,但是值得让它更容易使任何未来的代码移植。
Note: I'm using DWORD_PTR
because for 64 bit targets the bitmask is 64 bits wide. That nuance doesn't matter for you on XE but it's worth getting it right to make any future code porting easier.
这篇关于SetProcessAffinityMask - 选择多个处理器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!