如何使用 C 获取 Linux 中的 CPU 数量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4586405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 00:04:24  来源:igfitidea点击:

How to get the number of CPUs in Linux using C?

clinuxmultithreadingcpuprocessor

提问by Trevi?o

Is there an API to get the number of CPUs available in Linux? I mean, without using /proc/cpuinfo or any other sys-node file...

是否有用于获取 Linux 中可用 CPU 数量的 API?我的意思是,不使用 /proc/cpuinfo 或任何其他 sys-node 文件...

I've found this implementation using sched.h:

我使用 sched.h 找到了这个实现:

int GetCPUCount()
{
 cpu_set_t cs;
 CPU_ZERO(&cs);
 sched_getaffinity(0, sizeof(cs), &cs);

 int count = 0;
 for (int i = 0; i < 8; i++)
 {
  if (CPU_ISSET(i, &cs))
   count++;
 }
 return count;
}

But, isn't there anything more higher level using common libraries?

但是,使用公共库没有更高级别的东西吗?

采纳答案by Владимир Николайчук

#include <stdio.h>
#include <sys/sysinfo.h>

int main(int argc, char *argv[])
{
    printf("This system has %d processors configured and "
        "%d processors available.\n",
        get_nprocs_conf(), get_nprocs());
    return 0;
}

https://linux.die.net/man/3/get_nprocs

https://linux.die.net/man/3/get_nprocs

回答by chrisaycock

#include <unistd.h>
long number_of_processors = sysconf(_SC_NPROCESSORS_ONLN);

回答by R.. GitHub STOP HELPING ICE

Using /proc/cpuinfois the cleanest and most portable solution. In case the open fails, you could simply assume 1 cpu or 2 cpus. Code that depends on knowing the number of cpus for a purpose other than micro-optimizing (e.g. choosing the ideal number of threads to run) is almost surely doing something dumb.

使用/proc/cpuinfo是最干净、最便携的解决方案。如果打开失败,您可以简单地假设 1 个 cpu 或 2 个 cpu。出于微优化以外的目的(例如选择要运行的理想线程数)而依赖于了解 CPU 数量的代码几乎肯定会做一些愚蠢的事情。

The _SC_NPROCESSORS_ONLNsolution depends on a non-standard (glibc-specific) sysconfextension, which is a much bigger dependency than /proc(all Linux systems have /proc, but some have non-glibc libcs or older versions of glibc that lack _SC_NPROCESSORS_ONLN).

_SC_NPROCESSORS_ONLN解决方案依赖于非标准(glibc 特定)sysconf扩展,它比/proc(所有 Linux 系统都有/proc,但有些具有非 glibc libcs​​ 或缺少 的旧版 glibc _SC_NPROCESSORS_ONLN)具有更大的依赖性。

回答by Vikram.exe

This code (drawn from here) should work on both windows and *NIX platforms.

这段代码(从这里提取)应该适用于 windows 和 *NIX 平台。

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>


int main() {
  long nprocs = -1;
  long nprocs_max = -1;
#ifdef _WIN32
#ifndef _SC_NPROCESSORS_ONLN
SYSTEM_INFO info;
GetSystemInfo(&info);
#define sysconf(a) info.dwNumberOfProcessors
#define _SC_NPROCESSORS_ONLN
#endif
#endif
#ifdef _SC_NPROCESSORS_ONLN
  nprocs = sysconf(_SC_NPROCESSORS_ONLN);
  if (nprocs < 1)
  {
    fprintf(stderr, "Could not determine number of CPUs online:\n%s\n", 
strerror (errno));
    exit (EXIT_FAILURE);
  }
  nprocs_max = sysconf(_SC_NPROCESSORS_CONF);
  if (nprocs_max < 1)
  {
    fprintf(stderr, "Could not determine number of CPUs configured:\n%s\n", 
strerror (errno));
    exit (EXIT_FAILURE);
  }
  printf ("%ld of %ld processors online\n",nprocs, nprocs_max);
  exit (EXIT_SUCCESS);
#else
  fprintf(stderr, "Could not determine number of CPUs");
  exit (EXIT_FAILURE);
#endif
}

回答by RCL

sched_affinity()version you mention in the beginning is still better than /proc/cpuinfoand/or _SC_NPROCESSORS_ONLNsince it only counts CPUs available for a given process (some may be disabled by sched_setaffinity()invoked by an outside process). The only change would be using CPU_COUNT()instead of doing CPU_ISSETin a loop.

sched_affinity()您在开头提到的版本仍然比/proc/cpuinfo和/或_SC_NPROCESSORS_ONLN因为它只计算给定进程可用的 CPU 数(有些可能被sched_setaffinity()外部进程调用而被禁用)更好。唯一的变化是使用CPU_COUNT()而不是CPU_ISSET在循环中进行。

回答by Sunil Bojanapally

Another method scanning cpu* directories under sys file system:

另一种扫描sys文件系统下cpu*目录的方法:

#include<stdio.h>
#include <dirent.h>
#include <errno.h>
#define LINUX_SYS_CPU_DIRECTORY "/sys/devices/system/cpu"

int main() {
   int cpu_count = 0;
   DIR *sys_cpu_dir = opendir(LINUX_SYS_CPU_DIRECTORY);
   if (sys_cpu_dir == NULL) {
       int err = errno;
       printf("Cannot open %s directory, error (%d).\n", LINUX_SYS_CPU_DIRECTORY, strerror(err));
       return -1;
   }
   const struct dirent *cpu_dir;
   while((cpu_dir = readdir(sys_cpu_dir)) != NULL) {
       if (fnmatch("cpu[0-9]*", cpu_dir->d_name, 0) != 0)
       {
          /* Skip the file which does not represent a CPU */
          continue;
       }
       cpu_count++;
   }
   printf("CPU count: %d\n", cpu_count);
   return 0;
}

回答by Zibri

Personally for recent intel cpus I use this:

我个人对于最近的英特尔 CPU 使用这个:

int main()
{
unsigned int eax=11,ebx=0,ecx=1,edx=0;

asm volatile("cpuid"
        : "=a" (eax),
          "=b" (ebx),
          "=c" (ecx),
          "=d" (edx)
        : "0" (eax), "2" (ecx)
        : );

printf("Cores: %d\nThreads: %d\nActual thread: %d\n",eax,ebx,edx);
}

Output:

输出:

Cores: 4
Threads: 8
Actual thread: 1

Or, more concisely:

或者,更简洁地说:

#include <stdio.h>

int main()
{
unsigned int ncores=0,nthreads=0,ht=0;

asm volatile("cpuid": "=a" (ncores), "=b" (nthreads) : "a" (0xb), "c" (0x1) : );

ht=(ncores!=nthreads);

printf("Cores: %d\nThreads: %d\nHyperThreading: %s\n",ncores,nthreads,ht?"Yes":"No");

return 0;
}

Output:

输出:

Cores: 4
Threads: 8
HyperThreading: Yes