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

Tre*_*iño 56 c linux cpu multithreading processor

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

我已经使用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;
}
Run Code Online (Sandbox Code Playgroud)

但是,使用公共库是不是更高级别?

chr*_*ock 75

#include <unistd.h>
long number_of_processors = sysconf(_SC_NPROCESSORS_ONLN);
Run Code Online (Sandbox Code Playgroud)

  • 很好的解决方案,但似乎是 POSIX 的 Linux 扩展:http://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html (2认同)
  • @iDebD_gh 离线核心是什么意思? (2认同)

Vik*_*exe 20

此代码(从此处绘制)应适用于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
}
Run Code Online (Sandbox Code Playgroud)

  • 我不确定发布这个代码片段是否真的回答了OP的问题,尽管他们可能会从中反向设计一些有用的信息. (2认同)
  • 我同意 MarkR。chrisaycock 提供了一个简洁的答案。 (2认同)

小智 20

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 该答案给出的结果与问题中给出的片段不同。如果进程使用“taskset”绑定到机器上的 CPU 子集,则使用“sched_getaffinity()”的方法会给出分配的 CPU 数量,而“get_nprocs()”则给出机器上的 CPU 总数有可用的。如果您使用它来决定线程数量,这很糟糕,因为如果在多核计算机上只分配一个核心,那么进程就会崩溃。 (4认同)

R..*_*R.. 13

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

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

  • +1 OP似乎坚持自己上吊,所以我给了他绳索. (11认同)
  • / proc/cpuinfo以什么方式可移植?这是一个特定于Linux的接口(其他一些系统模拟它,例如,带有安装在/ proc中的linprocfs文件系统的FreeBSD).例如,FreeBSD支持sysconfig _SC_NPROCESSORS_ONLN. (9认同)
  • 它是可移植的,因为它不会阻止程序在不可用的系统上运行,而在`/ proc`没有特殊含义的系统上,管理员可以存储具有正确信息的简单文本文件在`/ proc/cpuinfo`中. (5认同)
  • 解析文件以获取低级别信息是完全原始的(如果文件格式在实现中发生变化或变化,则难以维护). (5认同)
  • 我想Ulrich Drepper给了他绳索.我真的不明白添加非标准的东西的动机,当有一个现有的,更清洁,更便携的方式来做同样的事情.(如果在程序中编写`_SC_NPROCESSORS_ONLN`,如果常量丢失则无法编译,但其他方式在运行时失败(失败`open`等),任何理智的代码都会处理失败情况.) (3认同)
  • @cHao:这是不真实的.关注CPU的数量(以及更多的超线程核心)只是"原始的",因为它是大多数非平凡的现代程序所需的基本信息(是的,它不再是1980年) .虽然其他操作系统在以编程方式获取此信息方面表现不佳(例如,在Windows下有35行代码带有循环和多个内存分配),但LInux方法"解析文本文件"简直荒谬.甚至更多,因为他们甚至无法就/ proc或/ sys是否正确的事情达成一致. (3认同)

RCL*_*RCL 11

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


小智 7

没有一个答案涉及sysconf(...)get_nprocs()不正确地遵守由 cpu 关联性限制的任务的处理器数量。

您需要这样的方法来获取任务可用的处理器数量:

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>

int nprocs()
{
  cpu_set_t cs;
  CPU_ZERO(&cs);
  sched_getaffinity(0, sizeof(cs), &cs);
  return CPU_COUNT(&cs);
}

int main()
{
  printf("procs=%d\n", nprocs());
  return 0;
}
Run Code Online (Sandbox Code Playgroud)


Zib*_*bri 6

我个人对于最近的英特尔 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);
}
Run Code Online (Sandbox Code Playgroud)

输出:

Cores: 4
Threads: 8
Actual thread: 1
Run Code Online (Sandbox Code Playgroud)

或者,更简洁地说:

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Cores: 4
Threads: 8
HyperThreading: Yes
Run Code Online (Sandbox Code Playgroud)