SetProcessAffinityMask-выбрать несколько процессоров?
Как использовать SetProcessAffinityMask для выбора нескольких логических процессоров?
в Диспетчере задач Windows вы можете сделать это в качестве примера:
Я является CreateProcess процедуры для этого:
type
TProcessPriority = (ptLow = 000040,
ptBelowNormal = 004000,
ptNormal = 000020,
ptAboveNormal = 008000,
ptHigh = 000080,
ptRealtime = 000100);
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.
вызов любого из них не выберите соответствующие процессоры по понятным причинам, они дают представление о том, что я хочу сделать:
SetProcessAffinityMask(ProcInfo.hProcess, 1 + 2);
SetProcessAffinityMask(ProcInfo.hProcess, 1 and 2);
например, выберите любой из процессоров для процесса, как показано в Диспетчере задач.
Как это сделать, используя массив, набор или что-то еще? Я не могу заставить его работать с несколькими значениями.
спасибо.
2 ответов
это битовая маска, как описано в документация.
маска сродства процесса-это битовый вектор, в котором каждый бит представляет логический процессор, на котором разрешено запускать потоки процесса.
- процессор 0 составляет $ 01.
- процессор 1 составляет $ 02.
- Процессор 2 составляет $ 04.
- процессор 3 составляет $ 08.
- Процессор 4 стоит 10 долларов.
и так далее. Вы можете использовать логические or
объединить их. Таким образом, процессоры 0 и 1 будут или
что равно
.
Я бы использовал оператор shift shl
для создания значений для определенных процессоров. Вот так:
function SingleProcessorMask(const ProcessorIndex: Integer): DWORD_PTR;
begin
Result := 1 shl (ProcessorIndex-1);
end;
вы можете легко расширить это, чтобы генерировать маски для списков процессоров с помощью logical or
в цикле.
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;
вы можете проверить, что процессор находится в битовой маске, например это:
function ProcessorInMask(const ProcessorMask: DWORD_PTR;
const ProcessorIndex: Integer): Boolean;
begin
Result := (SingleProcessorMask(ProcessorIndex) and ProcessorMask)<>0;
end;
Примечание: я использую DWORD_PTR
потому что для 64-битных целей маски-это 64-битные. Этот нюанс не имеет значения для вас на XE, но стоит получить его правильно, чтобы сделать любой будущий перенос кода проще.
это 32-битная битовая маска на моем XE (но это может быть 64-бит на 64-битном XE2!)
просто определите набор [0..31] где 0=cpu 1 и т. д.
затем введите результат в dword.
Так
var
cpuset : set of 0..31;
begin
cpuset:=[1,2]; // cpus 2 and 3
include (cpuset,5); // add cpu 6
SetProcessAffinityMask(ProcInfo.hProcess, dword(cpuset));