Jak uzyskać liczbę procesorów w Linuksie za pomocą C?

Czy istnieje API, aby uzyskać liczbę procesorów dostępnych w Linuksie? Bez używania /proc / cpuinfo ani żadnego innego pliku sys-node...

Znalazłem tę implementację przy użyciu 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;
}

Ale czy nie ma czegoś bardziej wyższego poziomu przy użyciu wspólnych bibliotek?

6 answers

#include <stdio.h>
#include <sys/sysinfo.h>
int
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

 6
Author: Владимир Николайчук,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-27 22:23:29
#include <unistd.h>
sysconf(_SC_NPROCESSORS_ONLN);
 68
Author: chrisaycock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-20 09:31:36

Ten kod (zaczerpnięty z Tutaj) powinien działać zarówno na platformach windows jak i *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
}
 16
Author: Vikram.exe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-21 20:33:28

Używanie /proc/cpuinfo jest najczystszym i najbardziej przenośnym rozwiązaniem. W przypadku, gdy otwarte nie powiedzie się, można po prostu założyć 1 procesor lub 2 procesory. Kod, który zależy od znajomości liczby procesorów w celu innym niż mikro-optymalizacja (np. wybór idealnej liczby wątków do uruchomienia), prawie na pewno robi coś głupiego.

Rozwiązanie _SC_NPROCESSORS_ONLN zależy od niestandardowego (specyficznego dla glibc) rozszerzenia sysconf, które jest znacznie większą zależnością niż /proc (wszystkie systemy linuksowe mają /proc, ale niektóre nie-glibc libcs lub starsze wersje glibc, które nie posiadają _SC_NPROCESSORS_ONLN).

 14
Author: R..,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-03 17:11:52

sched_affinity() wersja, o której wspomniałeś na początku, jest nadal lepsza niż /proc/cpuinfo i/lub _SC_NPROCESSORS_ONLN, ponieważ liczy tylko procesory dostępne dla danego procesu (niektóre mogą być wyłączone przez sched_setaffinity() wywoływane przez zewnętrzny proces). Jedyną zmianą byłoby użycie CPU_COUNT() zamiast wykonywania CPU_ISSET W pętli.

 9
Author: RCL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-25 01:38:18

Inna metoda skanowania katalogów cpu * w systemie plików sys:

#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;
}
 0
Author: Sunil Bojanapally,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-21 04:50:35