linux 在不编写任何代码的情况下,是否有一个命令可以检索当前shell的关联中可用内核的数量?

lc8prwob  于 2023-03-17  发布在  Linux
关注(0)|答案(1)|浏览(110)

假设是Linux,并且假设当前shell启动时可能受到任务集的限制,我可以编写一些代码来获取当前进程关联,如下所示

#include <vector>
#include <pthread.h>
#include <stdio.h>

int getNumberOfAvailableCores() {
    pthread_t self = pthread_self();
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    int res = ::pthread_getaffinity_np(self, sizeof(cpuset), &cpuset);
    int num_cores = 0;
    if ( res!=0 ) return -1;
    for (int j = 0; j < CPU_SETSIZE; j++) {
        if (CPU_ISSET(j, &cpuset)) ++num_cores;
    }
    return num_cores;
}

int main() {
    int num_cores = getNumberOfAvailableCores();
    printf( "%d\n", num_cores );
    return 0;
}

https://godbolt.org/z/TxT67WWT6
但是在我甚至没有安装编译器的机器上,有没有办法猜测可用内核的数量?
getconf _NPROCESSORS_ONLN将返回联机处理器的数量,但不考虑隔离的核心数量。对于grepping /proc/cpuinfolscpu也是如此。
我研究了/proc/self,但没有找到一种干净的方法。

6uxekuva

6uxekuva1#

您需要命令nproc
nproc-打印可用的处理单元数
关联掩码包含3个处理器的示例:

$ taskset --cpu-list 0,2,4 bash
$ nproc
3

如果nproc由于某种原因不可用,我以前的答案可能会有用:
taskset命令用于设置或检索给定pid的运行进程的CPU关联
taskset-p选项表示:

  • 在现有PID上操作,不启动新任务。

因此,您将得到一个十六进制数,其中包含进程的关联掩码。

$ taskset -p $$
pid 1643922's current affinity mask: fff

现在,您需要执行popcount(计算1的二进制表示数)。
然后,我们将该数字转换为二进制形式,然后计算1的个数。

taskset -p $$ | \
tr '[[:lower:]]' '[[:upper:]]' | \
sed -E 's/.*:\s*/ibase=16;obase=2;/' | bc | tr -d '0\n' | wc -c
  • tr '[[:lower:]]' '[[:upper:]]'-将taskset的输出转换为大写(因为bc需要大写的十六进制数字)。
  • sed -E 's/.*:\s*/ibase=16;obase=2;/'-删除taskset的文本输出,并将其替换为bc的指令。ibase是输入数字的基数(16 =十六进制),obase是我们希望用于输出的基数(2 =二进制)。
  • 此时,我们将得到ibase=16;obase=2;FFF
  • bc-读取ibase=16;obase=2;FFF并将FFF打印为111111111111
  • tr -d '0\n'-从bc的输出中删除所有零和换行符
  • wc -c-计算所有字符。

在我的例子中,关联掩码是fff,输出是12
测试:我在这里启动了一个有3个处理器的子shell,然后在该shell中使用上面的oneliner来解决这个问题:

$ taskset --cpu-list 0,2,4 bash
$ taskset -p $$ | \
> tr '[[:lower:]]' '[[:upper:]]' | \
> sed -E 's/.*:\s*/ibase=16;obase=2;/' | bc | tr -d '0\n' | wc -c
3

相关问题