如何通过命令行获取Linux系统的cpu /核数?

我有这个脚本,但我不知道如何获得打印输出中的最后一个元素:

cat /proc/cpuinfo | awk '/^processor/{print $3}'

最后一个元素应该是cpu数量减1。

718912 次浏览
grep -c ^processor /proc/cpuinfo

将计算以“processor”开头的行数;在# EYZ0

对于具有超线程的系统,可以使用

grep ^cpu\\scores /proc/cpuinfo | uniq |  awk '{print $4}'

它应该返回(例如)8(而上面的命令将返回16)

下面将给出超线程和非超线程系统上的“真实”内核数。至少它在我所有的测试中都有效。

awk -F: '/^physical/ && !ID[$2] { P++; ID[$2]=1 }; /^cpu cores/ { CORES=$2 };  END { print CORES*P }' /proc/cpuinfo

处理/proc/cpuinfo的内容是不必要的繁复。使用< >强nproc < / >强,它是coreutils的一部分,所以它应该在大多数Linux安装中可用。

命令nproc打印当前进程可用的处理单元数量,该数量可能小于在线处理器的数量。

要找到所有已安装的内核/处理器的数量,请使用nproc --all

在我的8核机器上:

$ nproc --all
8

对于物理核总数:

grep '^core id' /proc/cpuinfo |sort -u|wc -l

在多插座机器(或总是)上,将上面的结果乘以插座的数量:

echo $(($(grep "^physical id" /proc/cpuinfo | awk '{print $4}' | sort -un | tail -1)+1))

@mklement0使用lscpu给出了一个很好的答案。我在评论中写了一个更简洁的版本

如果你想这样做,让它在linux和OS X上工作,你可以这样做:

CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu)

不是我的网页,但是这个来自http://www.ixbrian.com/blog/?p=64&cm_mc_uid=89402252817914508279022&cm_mc_sid_50200000=1450827902的命令在centos上很适合我。即使启用了超线程,它也会显示实际的cpu。

# EYZ0

前言:

  • 基于# eyz0的答案的问题是,它们解析的信息是为人类消费,因此缺乏为机器解析设计的稳定格式:输出格式在不同平台和运行时条件下可能不同;在Linux上使用lscpu -p(在macOS上使用sysctl)绕过了这个问题。

  • getconf _NPROCESSORS_ONLN / getconf NPROCESSORS_ONLN不区分逻辑物理 cpu。


下面是一个sh (posix兼容)代码片段,它在Linux和macOS上工作,用于确定number of - online - logicalphysical cpu;详见评论。

Linux使用lscpu, macOS使用sysctl

注意术语: CPU是指操作系统所看到的最小的处理单元。非超线程内核每个对应1个CPU,而超线程内核包含多于1(通常为2)- logical - CPU.
Linux使用下面的分类法[1],从最小的单位开始:
# EYZ0 & lt;# EYZ1 & lt;# EYZ2 & lt;# EYZ3 & lt;# EYZ4 < br > 每一层包含下一层的1个或多个实例

#!/bin/sh


# macOS:           Use `sysctl -n hw.*cpu_max`, which returns the values of
#                  interest directly.
#                  CAVEAT: Using the "_max" key suffixes means that the *maximum*
#                          available number of CPUs is reported, whereas the
#                          current power-management mode could make *fewer* CPUs
#                          available; dropping the "_max" suffix would report the
#                          number of *currently* available ones; see [1] below.
#
# Linux:           Parse output from `lscpu -p`, where each output line represents
#                  a distinct (logical) CPU.
#                  Note: Newer versions of `lscpu` support more flexible output
#                        formats, but we stick with the parseable legacy format
#                        generated by `-p` to support older distros, too.
#                        `-p` reports *online* CPUs only - i.e., on hot-pluggable
#                        systems, currently disabled (offline) CPUs are NOT
#                        reported.


# Number of LOGICAL CPUs (includes those reported by hyper-threading cores)
# Linux: Simply count the number of (non-comment) output lines from `lscpu -p`,
# which tells us the number of *logical* CPUs.
logicalCpuCount=$([ $(uname) = 'Darwin' ] &&
sysctl -n hw.logicalcpu_max ||
lscpu -p | egrep -v '^#' | wc -l)


# Number of PHYSICAL CPUs (cores).
# Linux: The 2nd column contains the core ID, with each core ID having 1 or
#        - in the case of hyperthreading - more logical CPUs.
#        Counting the *unique* cores across lines tells us the
#        number of *physical* CPUs (cores).
physicalCpuCount=$([ $(uname) = 'Darwin' ] &&
sysctl -n hw.physicalcpu_max ||
lscpu -p | egrep -v '^#' | sort -u -t, -k 2,4 | wc -l)


# Print the values.
cat <<EOF
# of logical CPUs:  $logicalCpuCount
# of physical CPUS: $physicalCpuCount
EOF

[1] # EYZ1

注意,除了macOS之外的bsd衍生系统——例如,FreeBSD——只支持sysctlhw.ncpu键,这在macOS上是不支持的;我不清楚哪个新键hw.npu对应于:hw.(logical|physical)cpu_[max]

感谢@teambob帮助纠正了physical-CPU-count lscpu命令。

警告: lscpu -p输出不包括“book”列(man页面提到“books”作为分类层次结构中套接字和节点之间的实体)。如果在给定的Linux系统(有人知道时间和方式吗?)上正在使用“books”,则physical-CPU-count命令可能会-report(这是基于lscpu报告的id不是唯一的跨越更高层次的实体;例如:来自2个不同插座的2个不同内核可能具有相同的ID)。


如果你使用将上面的代码保存为shell脚本cpus,让它与chmod +x cpus可执行,并将其放在你的$PATH文件夹中,你会看到如下输出:

$ cpus
logical  4
physical 4

[1] Xaekai揭示了什么是book: "a book是一个模块,它包含一个带有CPU插座、RAM插座、沿边缘的IO连接和用于冷却系统集成的钩子的电路板。它们用于IBM大型机。进一步信息:http://ewh.ieee.org/soc/cpmt/presentations/cpmt0810a.pdf"

我发现的最可移植的解决方案是getconf命令:

getconf _NPROCESSORS_ONLN

它在Linux和Mac OS x上都可以工作,与其他一些方法相比,它的另一个好处是getconf已经存在很长时间了。我必须在一些较旧的Linux机器上进行开发,它们没有nproclscpu命令可用,但它们有getconf命令。

编者注:虽然getconf 实用程序是posix强制的,但具体的_NPROCESSORS_ONLN_NPROCESSORS_CONF 不是。 也就是说,如前所述,它们可以在Linux平台和macOS上运行;在FreeBSD/PC-BSD上,你必须省略开头的_.

可以通过以下两种方式确定“物理”的CPU核数。

  • 计数唯一核心id的数量(大致相当于grep -P '^core id\t' /proc/cpuinfo | sort -u | wc -l)。

    # EYZ0 < / p >

  • 将“每个插座的核心数”乘以插座数。

    # EYZ0 < / p >

  • 计算Linux内核使用的唯一逻辑CPU的数量。-p选项生成输出以方便解析,并且与lscpu的早期版本兼容。

    # EYZ0 < / p >


重申一下其他人所说的,有一些相关的属性。

要确定可用的处理器数量:

getconf _NPROCESSORS_ONLN
grep -cP '^processor\t' /proc/cpuinfo

确定可用的处理单元数量(不一定与内核数量相同)。这是超线程感知的。

nproc

我不想说得太深,但是您还可以通过getconf _NPROCESSORS_CONF确定已配置处理器的数量(而不是简单的可用/在线处理器)。要确定CPU的总数(离线和在线),您需要解析lscpu -ap的输出。

你也可以使用Python!获取物理核数:

$ python -c "import psutil; print(psutil.cpu_count(logical=False))"
4

获取超线程核的数量:

$ python -c "import psutil; print(psutil.cpu_count(logical=True))"
8
使用getconf确实是最可移植的方式,但是变量在BSD和Linux中与getconf有不同的名称,所以你必须测试这两个,正如要点所示: https://gist.github.com/jj1bdx/5746298 < a href = " https://gist.github.com/jj1bdx/5746298 " > < / > (还包括使用ksh的Solaris修复)

我个人使用:

$ getconf _NPROCESSORS_ONLN 2>/dev/null || getconf NPROCESSORS_ONLN 2>/dev/null || echo 1

如果你想在python中使用这个,你可以通过导入os模块来使用getconf使用的syscall:

$ python -c 'import os; print os.sysconf(os.sysconf_names["SC_NPROCESSORS_ONLN"]);'

至于nproc,它是GNU Coreutils的一部分,所以默认情况下在BSD中不可用。它在其他一些方法之后也使用sysconf()。

使用awk计算每个“物理id”方法的“核心id”,如果“核心id”不可用,则返回“处理器”计数(如覆盆子)

echo $(awk '{ if ($0~/^physical id/) { p=$NF }; if ($0~/^core id/) { cores[p$NF]=p$NF }; if ($0~/processor/) { cpu++ } } END { for (key in cores) { n++ } } END { if (n) {print n} else {print cpu} }' /proc/cpuinfo)

下面是我用来计算Linux上在线物理内核数量的方法:

lscpu --online --parse=Core,Socket | grep --invert-match '^#' | sort --unique | wc --lines

简而言之:

lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l

示例(1个socket):

> lscpu
...
CPU(s):                28
Thread(s) per core:    2
Core(s) per socket:    14
Socket(s):             1
....
> lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l
14

示例(2个socket):

> lscpu
...
CPU(s):                56
Thread(s) per core:    2
Core(s) per socket:    14
Socket(s):             2
...
> lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l
28

示例(4个socket):

> lscpu
...
CPU(s):                64
Thread(s) per core:    2
Core(s) per socket:    8
Socket(s):             4
...
> lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l
32

Linux、MacOS、Windows跨平台解决方案:

CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu || echo "$NUMBER_OF_PROCESSORS")
cat /proc/cpuinfo | grep processor

这工作得很好。当我尝试第一个答案时,我得到了3个CPU的输出。我知道我在系统上有4个cpu,所以我只是为处理器做了一个grep,输出看起来像这样:

[root@theservername ~]# cat /proc/cpuinfo | grep processor
processor       : 0
processor       : 1
processor       : 2
processor       : 3
 dmidecode  | grep -i cpu | grep Version

给我

版本:Intel(R) Xeon(R) CPU E5-2667 v4 @ 3.20GHz

版本:Intel(R) Xeon(R) CPU E5-2667 v4 @ 3.20GHz

这是正确的套接字计数-查找E5-2667告诉我每个套接字都有8 cores,所以相乘,最终得到16 cores横跨2 sockets

哪里lscpu给我20 CPUs -这是完全不正确的-不知道为什么。(同理,cat /proc/cpu -以20结束。

更快,不用叉子

这适用于几乎所有

ncore=0
while read line ;do
[ "$line" ] && [ -z "${line%processor*}" ] && ncore=$((ncore+1))
done </proc/cpuinfo
echo $ncore
4

为了与等保持兼容,我使用了ncore=$((ncore+1))而不是((ncore++))

# EYZ0版本

ncore=0
while read -a line ;do
[ "$line" = "processor" ] && ((ncore++))
done </proc/cpuinfo
echo $ncore
4

lscpu收集CPU架构信息表单/proc/cpuinfon以人类可读的格式:

# lscpu




Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    1
Core(s) per socket:    4
CPU socket(s):         2
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 15
Stepping:              7
CPU MHz:               1866.669
BogoMIPS:              3732.83
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
NUMA node0 CPU(s):     0-7

参见https://unix.stackexchange.com/questions/468766/understanding-output-of-lscpu

如果你可以使用Python,那么numexpr模块有一个函数:

In [5]: import numexpr as ne


In [6]: ne.detect_number_of_cores()
Out[6]: 8

也:

In [7]: ne.ncores
Out[7]: 8

从命令提示符中查询该信息使用:

# runs whatever valid Python code given as a string with `-c` option
$ python -c "import numexpr as ne; print(ne.ncores)"
8

或者简单地说,可以从multiprocessing.cpu_count()函数中获得此信息

$ python -c "import multiprocessing; print(multiprocessing.cpu_count())"

或者更简单地使用os.cpu_count()

$ python -c "import os; print(os.cpu_count())"

Python 3还提供了一些简单的方法来获取它:

$ python3 -c "import os; print(os.cpu_count());"

4

$ python3 -c "import multiprocessing; print(multiprocessing.cpu_count())"

4

我也认为cat /proc/cpuinfo会给我正确的答案,但是我最近看到我的ARM四核Cortex A53系统只显示了一个单核。似乎/proc/cpuinfo只显示活动的内核,而:

# EYZ0

能更好地衡量那里有什么。你也可以

# EYZ0

查看哪些内核在线,以及

# EYZ0

查看哪些核心处于脱机状态。onlineofflinepresent sysfs条目返回cpu的索引,因此0的返回值仅表示核0,而1-3的返回值则表示核1、2和3。

看到# EYZ0

如果您只想计算物理内核,这个命令可以满足我的需要。

lscpu -e | tail -n +2 | tr -s " " | cut -d " " -f 4 | sort | uniq | wc -w

非常基本,但似乎是计算实际的物理内核,忽略了逻辑计数

使用下面的查询获取核心细节

[oracle@orahost](TESTDB)$ grep -c ^processor /proc/cpuinfo
8
< p >概要: 要得到物理cpu,这样做:

grep 'core id' /proc/cpuinfo | sort -u

要获得物理逻辑 cpu,请执行以下操作:

grep -c ^processor /proc/cpuinfo

# EYZ0 & lt; & lt;这是您需要的关于流程和的任何信息的黄金来源

# EYZ0 & lt; & lt;是任何CPU信息的黄金来源。

这很简单。只需使用这个命令:

lscpu

Fravadona的回答很好,也很正确,但它需要lscpu的存在。因为在我需要物理核数的系统上不存在它,所以我试图提出一个只依赖于proc/cpuinfo的系统

# EYZ0

它工作得很完美,但不幸的是,它没有Fravadona的那么坚固,因为它会崩溃

  • /proc/cpuinfo中字段的名称或顺序会发生变化
  • grep将它插入的行分隔符(目前是--)替换为其他字符串。

但是,除此之外,它完美无缺:)

以下是对正在发生的一切的快速解释

grep -B2 'core id'

只获取我们感兴趣的行(即“核心id”;和前面的两行)

sed 's/siblings.*/'/

删除“兄弟姐妹”;行

tr -d '[:space:]'

替换空格字符

sed 's/--/\n/'g

用换行符替换由grep插入的'——'字符

sort -u

按“物理id,核心id”分组;

wc -l

数一下行数

作为一个完全的菜鸟,我对自己很满意。我从来没有想过我能把需要的行按“物理id”组合在一起。以及“核心id”。这有点俗气,但很管用。

如果有任何专家知道如何简化这种混乱,请告诉我。

上述答案适用于大多数情况,但如果你在docker容器环境中,你的容器受到CpusetCpus的限制,那么你实际上不能通过上面的方法获得真正的cpu内核

在这种情况下,你需要这样做来获得真正的cpu内核:

grep -c 'cpu[0-9]' /proc/stat

如果有人想知道,下面是Python psutil.cpu_count(logical=False)调用在Linux上的等效shell脚本:

cat /sys/devices/system/cpu/cpu[0-9]*/topology/core_cpus_list | sort -u | wc -l

这里有一个稍长的版本,如果core_cpus_list不可用,它会返回到已弃用的thread_siblings_list文件中的信息(psutil有这个后退):

cat /sys/devices/system/cpu/cpu[0-9]*/topology/{core_cpus_list,thread_siblings_list} | sort -u | wc -l

这个帖子中的大多数答案都与逻辑核有关。

在Ubuntu 18上使用BaSH。x,我发现这可以很好地确定物理数量 cpu:

numcpu="$(lscpu | grep -i 'socket(s)' | awk '{print $(2)}')"

它应该可以在大多数Linux发行版上运行。

在之前的众多答案中又多了一个。当cgroup可用时,可以使用它们。cpuset子系统提供活动cpu的列表。它可以列在层次结构/ sys / fs / cgroup中最上面的cgroup中。例如:

$ cat /sys/fs/cgroup/cpuset/cpuset.effective_cpus
0-3

然后,需要对后者进行解析,以获得活动cpu的数量。该文件的内容是一个以逗号分隔的CPU集列表。

下面是一个示例,使用tr将列表分解为单个表达式,并使用sed将间隔转换为传递给expr的算术运算:

#!/bin/sh


# For test purposes, the CPU sets are passed as parameters
#cpuset=`cat /sys/fs/cgroup/cpuset/cpuset.effective_cpus`
cpuset=$1


ncpu=0
for e in `echo $cpuset | tr ',' ' '`
do
case $e in


# CPU interval ==> Make an arithmetic operation
*-*) op=`echo $e | sed -E 's/([0-9]+)-([0-9]+)/\2 - \1 + 1/'`;;


# Single CPU number
*) op=1;;


esac


ncpu=`expr $ncpu + $op`


done


echo $ncpu

下面是一些使用不同CPU集执行的例子:

$ for cpuset in "0" "0,3" "0-3" "0-3,67" "0-3,67,70-75" "0,1-3,67,70-75"
> do
>   ncpu.sh $cpuset
> done
1
2
4
5
11
11

考虑到打印可用CPU内核信息的特定示例代码片段,例如:

$ cat /proc/cpuinfo | awk '/^processor/{print $3}'

两种方法

根据最高的cpu核心id值得出总价值

利用CPU核心有一个连续的数字附加到它们并存储在processor字段下的优势。由于每个CPU核心存储在proc文件中的信息是在一个由processor字段升序排列的列表中,您可以简单地获取该序列的最后一个条目并观察processor字段中的数值。

$ cat /proc/cpuinfo | awk '/^processor/{print $3}' | tail -n 1

注意:由于/proc/cpuinfo保存了与cpu计数对应的一些条目,processor字段的初始值为0,不要忘记将最后一个cpu核心的值增加1。

$ last_cpu_core_id=$(/proc/cpuinfo | awk '/^processor/{print $3}' | tail -n 1)
$ echo $((last_cpu_core_id + 1))

计算输出的行数

这种方法与第一种方法相反,我们并不真正关心cpu核心id的特定值,我们只是计算输出行数。当涉及到计数时,这个过程通常从1开始,这简化了我们的解决方案。

使用# EYZ0

$ cat /proc/cpuinfo | grep processor | wc -l

或者,我们不必记住processor字段本身,而是利用描述单个cpu核心细节的每个条目由换行符分隔的事实。

cat /proc/cpuinfo | grep -v '^\w' | wc -l

使用# EYZ0

cat /proc/cpuinfo | awk '($1 == "processor") {count++ } END { print count }'