GNU coreutils中的nproc实用程序的工作原理确实有些微妙。如果您查看手册页,它甚至是第一句话:
打印当前进程可用的处理单元数量,该数量可能少于在线处理器的数量。
那么,这实际上意味着什么?好吧,仅仅因为计算机上运行的某些代码具有一定数量的CPU(在这里我指的是“硬件线程数量”)并不一定意味着您可以生成一个使用那么多进程的进程。有个简单的例子吗?容器!您知道吗,当您调用docker运行一个容器时,可以轻松地限制该容器可以使用多少CPU?在这种情况下,我们要考虑--cpuset-cpus参数,因为--cpus的工作原理有所不同。
$ nproc8 $ docker run --cpuset-cpus = 0-1 --rm = true -it amazonlinux:2bash-4.2#nproc2bash-4.2#exit $ docker run --cpuset-cpus = 0-2 --rm = true-它amazonlinux:2bash-4.2#nproc3
如您所见,nproc在这里可以获得正确的信息,因此,如果您要进行计算,例如“请使用最多可用的CPU”,作为软件配置的参数(例如运行多少个线程),您将获得正确的数字。
$ / usr / bin / lscpu -p | grep -c“ ^ [0-9]” 8 $ grep -c'processor'/ proc / cpuinfo 8 $ docker run --cpuset-cpus = 0-1 --rm = true -it amazonlinux:2bash-4.2#yum安装-y /usr/bin/lscpu......bash-4.2# / usr / bin / lscpu -p | grep -c“ ^ [0-9]” 8bash-4.2#grep -c'处理器'/ proc / cpuinfo 8bash-4.2#nproc2
在这种情况下,如果您的线程数量基于grepping lscpu,则您将获得另一个依赖项(在util-linux程序包上),这不是必需的。您也会得到错误的答案,就像通过grepping / proc / cpuinfo所做的一样。因此,最终将要做的只是增加上下文切换的数量,可能还会增加性能下降。当然,这不仅可能是在Docker容器中出现的问题,还可以使用与docker在任何要控制进程资源的地方使用的机制相同的机制。
需要注意的另一点微妙的事情是/ proc / cpuinfo内容的差异取决于CPU体系结构。您可能认为今天不是问题,但是谁愿意不必要地调试某些东西?
tl; dr:用于确定“要运行多少个进程”:请使用nproc,请不要grep lscpu或/ proc / cpuinfo