使用C获取Linux中的CPU数量
有没有一个API来获取Linux中可用的CPU数量? 我的意思是,不使用/ proc / cpuinfo或任何其他系统节点文件…
我发现这个实现使用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; }
但是,使用通用库不会有更高的水平吗?
#include <unistd.h> sysconf(_SC_NPROCESSORS_ONLN);
使用/proc/cpuinfo
是最简洁和最便携的解决scheme。 如果打开失败,你可以简单地假设1个CPU或2个CPU。 依赖于知道cpus的数量而不是微观优化的代码(例如,select理想的线程数来运行)几乎肯定会做一些愚蠢的事情。
_SC_NPROCESSORS_ONLN
解决scheme依赖于一个非标准(特定于glibc)的sysconf
扩展,它比/proc
更大的依赖(所有的Linux系统都有/proc
,但是有一些扩展是非glibc libcs或者老版本的缺less_SC_NPROCESSORS_ONLN
的glibc) 。
这个代码(从这里开始 )应该可以在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 }
你在开始时提到的sched_affinity()
版本仍然比/proc/cpuinfo
和/或_SC_NPROCESSORS_ONLN
因为它只计算给定进程可用的CPU(有些可能被外部进程调用的sched_setaffinity()
禁用)。 唯一的变化是使用CPU_COUNT()
而不是在一个循环中做CPU_ISSET
。
在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; }