如何通过C#获取机器的CPU个数?

咨询区

  • MrGreggles

我的项目需要获取当前机器的CPU核数,包括物理CPU,逻辑CPU。.

回答区

  • ToddBFisher

你可以通过 C# 提取关于 处理器 的一下三种信息。

  1. 物理处理器个数

  2. 核数

  3. 逻辑处理器个数

它们是不同的概念,比如说:一个机器支持超线程的双核处理器, 那么2个物理处理器,拥有4核,8个逻辑处理器。

要想获取 逻辑处理器 的个数,可以直接用 C# 内置的 Environment 即可,但如果想获取其他方面的信息,只能用 WMI 来实现了,或许还要给系统安装一些补丁。

接下来引用 System.Management.dll 工具包,然后我们一起来看一看。

  1. 物理处理器个数
        static void Main(string[] args)
        {
            foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
            {
                Console.WriteLine("Number Of Physical Processors: {0} ", item["NumberOfProcessors"]);
            }
        }
  1. 核数
        static void Main(string[] args)
        {
            int coreCount = 0;
            foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
            {
                coreCount += int.Parse(item["NumberOfCores"].ToString());
            }
            Console.WriteLine("Number Of Cores: {0}", coreCount);
        }
  1. 逻辑处理器
        static void Main(string[] args)
        {
            Console.WriteLine("Number Of Logical Processors: {0}", Environment.ProcessorCount);
        }

或者用 WMI 来实现也可以。

        static void Main(string[] args)
        {
            foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
            {
                Console.WriteLine("Number Of Logical Processors: {0}", item["NumberOfLogicalProcessors"]);
            }
        }
  • Fab

可以通过 PInvoke 的方式调用 Kernel32.dll,具体参考如下代码:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SYSTEM_INFO
{
  public ushort wProcessorArchitecture;
  public ushort wReserved;
  public uint dwPageSize;
  public IntPtr lpMinimumApplicationAddress;
  public IntPtr lpMaximumApplicationAddress;
  public IntPtr dwActiveProcessorMask;
  public uint dwNumberOfProcessors;
  public uint dwProcessorType;
  public uint dwAllocationGranularity;
  public ushort wProcessorLevel;
  public ushort wProcessorRevision;
}

internal static class SystemInfo 
{
    static int _trueNumberOfProcessors;
    internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);    

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    internal static extern void GetSystemInfo(out SYSTEM_INFO si);

    [DllImport("kernel32.dll")]
    internal static extern int GetProcessAffinityMask(IntPtr handle, out IntPtr processAffinityMask, out IntPtr systemAffinityMask);

    internal static int GetNumProcessCPUs()
    {
      if (SystemInfo._trueNumberOfProcessors == 0)
      {
        SYSTEM_INFO si;
        GetSystemInfo(out si);
        if ((int) si.dwNumberOfProcessors == 1)
        {
          SystemInfo._trueNumberOfProcessors = 1;
        }
        else
        {
          IntPtr processAffinityMask;
          IntPtr systemAffinityMask;
          if (GetProcessAffinityMask(INVALID_HANDLE_VALUE, out processAffinityMask, out systemAffinityMask) == 0)
          {
            SystemInfo._trueNumberOfProcessors = 1;
          }
          else
          {
            int num1 = 0;
            if (IntPtr.Size == 4)
            {
              uint num2 = (uint) (int) processAffinityMask;
              while ((int) num2 != 0)
              {
                if (((int) num2 & 1) == 1)
                  ++num1;
                num2 >>= 1;
              }
            }
            else
            {
              ulong num2 = (ulong) (long) processAffinityMask;
              while ((long) num2 != 0L)
              {
                if (((long) num2 & 1L) == 1L)
                  ++num1;
                num2 >>= 1;
              }
            }
            SystemInfo._trueNumberOfProcessors = num1;
          }
        }
      }
      return SystemInfo._trueNumberOfProcessors;
    }
}

点评区

很多关于 windows 上的软硬件信息,用 WMI 组件提取确实非常方便,学习了。