将进程添加到具有指定组的作业后,无法设置处理器关联

时间:2017-11-07 05:37:56

标签: c# winapi process processor affinity

我基本上尝试使用指定的NUMA组和处理器关联来启动新进程。 我在C#中这样做。 设置进程的ProcessorAffinity属性对我不起作用,因为它只适用于第一个NUMA组。

我正在创建一个作业对象,为作业设置组,然后将该过程添加到作业中。 这会更改NUMA组的流程。但是,一旦我这样做,我就无法为该过程设置处理器亲和力。

SetProcessAffinityMask返回true,但GetProcessAffinityMask返回与之前相同的值。

在将流程添加到作业之前设置关联掩码,但是一旦将流程添加到作业中,亲缘关系就会生效。

我的测试代码(如下)写入控制台:

  • 将SetProcessAffinityMask调用为1
  • GetProcessAffinityMask现在返回1
  • 将作业组设置为0
  • 向作业添加流程。
  • GetProcessAffinityMask现在返回15
  • 再次调用SetProcessAffinityMask为1
  • GetProcessAffinityMask现在返回15

我希望将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
        }
    }
}

0 个答案:

没有答案