我基本上尝试使用指定的NUMA组和处理器关联来启动新进程。
我在C#中这样做。
设置进程的ProcessorAffinity
属性对我不起作用,因为它只适用于第一个NUMA组。
我正在创建一个作业对象,为作业设置组,然后将该过程添加到作业中。 这会更改NUMA组的流程。但是,一旦我这样做,我就无法为该过程设置处理器亲和力。
SetProcessAffinityMask
返回true,但GetProcessAffinityMask
返回与之前相同的值。
在将流程添加到作业之前设置关联掩码,但是一旦将流程添加到作业中,亲缘关系就会生效。
我的测试代码(如下)写入控制台:
我希望将GetProcessAffinityMask
返回的最后一个值设置为1或者在将处理添加到作业时根本不更改为15。
任何帮助都将不胜感激。
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ChangeGroupUsingJob
{
class Program
{
static void Main(string[] args)
{
// start the process
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "notepad.exe"
}
};
process.Start();
UIntPtr targetAffinityMask = new UIntPtr(1);
Console.WriteLine("Calling SetProcessAffinityMask to " + targetAffinityMask);
if (!SetProcessAffinityMask(process.Handle, targetAffinityMask))
Console.WriteLine("Error code: " + Marshal.GetLastWin32Error());
ReportProcessAffinityMask(process);
// create job
var jobObjectHandle = CreateJobObject(IntPtr.Zero, null);
ushort group = 0;
int length = Marshal.SizeOf(typeof(ushort));
IntPtr groupInfoPtr = Marshal.AllocHGlobal(length);
Marshal.StructureToPtr(group, groupInfoPtr, false);
Console.WriteLine("Setting job group to " + group);
// set job info
var jobInfoSet = SetInformationJobObject(jobObjectHandle, JobObjectInfoType.GroupInformation, groupInfoPtr, (uint)length);
Console.WriteLine("Adding process to the job.");
// assign process to the job
var processAddedToJob = AssignProcessToJobObject(jobObjectHandle, process.Handle);
ReportProcessAffinityMask(process);
Console.WriteLine("Calling again SetProcessAffinityMask to " + targetAffinityMask);
if (!SetProcessAffinityMask(process.Handle, targetAffinityMask))
Console.WriteLine("Error code: " + Marshal.GetLastWin32Error());
ReportProcessAffinityMask(process);
// close the job (process should still keep running)
var handleClosed = CloseHandle(jobObjectHandle);
Console.ReadLine();
}
private static void ReportProcessAffinityMask(Process process)
{
UIntPtr processAffinityMask;
UIntPtr systemAffinityMask;
bool getProcessAffinityMaskSuccess;
getProcessAffinityMaskSuccess = GetProcessAffinityMask(process.Handle, out processAffinityMask, out systemAffinityMask);
Console.WriteLine("GetProcessAffinityMask now returns " + processAffinityMask);
}
[DllImport(dllName: "kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern IntPtr CreateJobObject(IntPtr securityAttributes, string name);
[DllImport(dllName: "kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll")]
static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetProcessAffinityMask(IntPtr process, UIntPtr processAffinityMask);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetProcessAffinityMask(IntPtr hProcess, out UIntPtr lpProcessAffinityMask, out UIntPtr lpSystemAffinityMask);
public enum JobObjectInfoType
{
AssociateCompletionPortInformation = 7,
BasicLimitInformation = 2,
BasicUIRestrictions = 4,
EndOfJobTimeInformation = 6,
ExtendedLimitInformation = 9,
SecurityLimitInformation = 5,
GroupInformation = 11
}
}
}