coreutils8.32 nproc命令和源码分析

命令功能:默认查询进程可用的cpu数,--all查询cpu总数,--ignore xxx是减少x个进程可用cpu数

/* 执行流程:默认将用于获取进程可用cpu数的常量(NPROC_CURRENT_OVERRIDABLE)赋值到mode。(如果开启了--all就将mode切换成查询cpu总数(NPROC_ALL))。如果开启了--ignore就调用xdectoumax减少进程可用cpu总数,然后刚好后面获取cpu数量的函数(就会获取到ignore减少后的进程可用cpu) */

/* 核心函数:(1) xdectoumax用于减少进程可用cpu的数量。

(2) num_processors按照传入的常量的对应方式获取cpu数量 */ 

#include <config.h>
#include <getopt.h>
#include <stdio.h>
#include <sys/types.h>

#include "system.h"
#include "error.h"
#include "nproc.h"
#include "quote.h"
#include "xdectoint.h"

/* 程序名 */
#define PROGRAM_NAME "nproc"

/* 作者名 */
#define AUTHORS proper_name ("Giuseppe Scrivano")

/* 枚举:用于判断选项 */
enum
{
  ALL_OPTION = CHAR_MAX + 1,
  IGNORE_OPTION  /* CHAR_MAX + 2 */
};

/* 选项处理 */
static struct option const longopts[] =
{
  {"all", no_argument, NULL, ALL_OPTION},  /* cpu总数 */
  {"ignore", required_argument, NULL, IGNORE_OPTION},  /* 设置忽视多少个cpu */
  {GETOPT_HELP_OPTION_DECL},
  {GETOPT_VERSION_OPTION_DECL},
  {NULL, 0, NULL, 0}
};

/* 提示函数 */
void
usage (int status)
{
  if (status != EXIT_SUCCESS)
    emit_try_help ();
  else
    {
      printf (_("Usage: %s [OPTION]...\n"), program_name);
      fputs (_("\
Print the number of processing units available to the current process,\n\
which may be less than the number of online processors\n\
\n\
"), stdout);
      fputs (_("\
      --all      print the number of installed processors\n\
      --ignore=N  if possible, exclude N processing units\n\
"), stdout);

      fputs (HELP_OPTION_DESCRIPTION, stdout);
      fputs (VERSION_OPTION_DESCRIPTION, stdout);
      emit_ancillary_info (PROGRAM_NAME);
    }
  exit (status);
}

int
main (int argc, char **argv)
{
  /* 初始化 */
  unsigned long nproc, ignore = 0; /* nproc保存了cpu数量。ignore保存了减少的cpu数量 */
  initialize_main (&argc, &argv);
  set_program_name (argv[0]);
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  atexit (close_stdout);

  /* nproc_query类型在nproc.h内定义
   * mode是用于判断要获取怎样的cpu数的掩码。默认:通过环境变量获取当前进程可用的cpu数量 */
  enum nproc_query mode = NPROC_CURRENT_OVERRIDABLE;

  while (1)
    {
      int c = getopt_long (argc, argv, "", longopts, NULL);
      if (c == -1)
        break;
      switch (c)
        {
        case_GETOPT_HELP_CHAR;

        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);

        case ALL_OPTION:
          mode = NPROC_ALL;
          break;

        case IGNORE_OPTION:
          /* xdectoumax是减少进程可用的cpu数,进程至少会保留1个可用cpu,返回值:减少的cpu总数 */
          ignore = xdectoumax (optarg, 0, ULONG_MAX, "", _("invalid number"),0);
          break;

        default:
          usage (EXIT_FAILURE);
        }
    }

  /* 选项错误 */
  if (argc != optind)
    {
      error (0, 0, _("extra operand %s"), quote (argv[optind]));
      usage (EXIT_FAILURE);
    }
    
  /* 函数功能:传入nproc枚举的三个常量然后返回对应值
   * (1) 默认:NPROC_CURRENT_OVERRIDABLE 通过环境变量获取当前进程可用的cpu数量(可以被环境变量改写)
   * (2) 启用--all选项后将mode设为NPROC_ALL
   * (3) NPROC_CURRENT 和默认的NPROC_CURRENT_OVERRIDABL差不多,获取当前进程可用的cpu数量(只是不能通过环境变量改写)
   * 没有找到num_processors具体实现 
   */
  nproc = num_processors (mode);

  /* 获取xdectoumax减少后的可用cpu数量,进程至少保留1个可用cpu */
  if (ignore < nproc)
    nproc -= ignore;
  else
    nproc = 1;

  printf ("%lu\n", nproc);

  return EXIT_SUCCESS;
}

 nproc.h定义了nproc_query枚举类型。用于num_processors函数的参数,来选择获取cpu数量的方式

/* Detect the number of processors.

   Copyright (C) 2009-2020 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, see <https://www.gnu.org/licenses/>.  */

/* Written by Glen Lenker and Bruno Haible.  */

/* Allow the use in C++ code.  */
#ifdef __cplusplus
extern "C" {
#endif

/* A "processor" in this context means a thread execution unit, that is either
   - an execution core in a (possibly multi-core) chip, in a (possibly multi-
     chip) module, in a single computer, or
   - a thread execution unit inside a core
     (hyper-threading, see <https://en.wikipedia.org/wiki/Hyper-threading>).
   Which of the two definitions is used, is unspecified.  */

enum nproc_query
{
  NPROC_ALL,                 /* 处理器总数 */
  NPROC_CURRENT,             /* 当前进程可用的处理器 */
  NPROC_CURRENT_OVERRIDABLE  /* 类似当前进程可用的处理器,但是可以通过环境变量OMP_NUM_THREADS重写*/
};

/* 返回处理器总数,结果至少是1  */
extern unsigned long int num_processors (enum nproc_query query);

#ifdef __cplusplus
}
#endif /* C++ */

 

Coreutils 软件包包括一整套基本的 shell 工具。 basename 去掉文件名中的目录和后缀 cat 把文本文件的内容发送到标准输出 chgrp 改变文件和目录属组,属组可以使用组名或者组识别号表示 chmod 改变文件和目录的权限,权限可以使用符号或者八进制两种表达方式 chown 改变文件和目录的所有权(包括用户和/或组) chroot 使用特定的目录作为执行某个命令或者交互 shell 的根目录(/)。在多数系统中,只有 root 用户能运行这个命令 cksum 输出指定的每个文件的CRC(循环冗余校验)校验和与字节数 comm 一行一行对两个已经排序的文件进行比较,在第三列中显示同一行是否相同 cp 复制文件 csplit 把一个文件按照给定的模式或者行号分成几块 cut 从指定的文件中提取特定的列送到标准输出 date 以特定的格式显示当前时间,或者设置系统日期 dd 以可选块长度复制文件,默认情况下从标准输入设备输出到标准输出设备。复制过程中,还可以对文件进行一些转换。 df 显示参数中的文件所在分区磁盘空间的使用情况,如果没有给出文件参数就显示所有已经安装的文件系统的可用空间数量。 dir 同 ls dircolors 设置 LS_COLOR 环境变量(用来改变 ls 及相关工具默认颜色组合)。 dirname 显示从文件名去掉非目录后缀之后的内容 du 显示参数使用的磁盘空间的数量,对于参数为目录还会列出每个子目录磁盘空间占用情况。 echo 显示给定字符串或变量值 env 在一个被修改的环境中运行一个程序 expand 把 tab 转换为空格符 expr 执行表达式计算 factor 输出所有指定整数的质因数 false 返回一个不成功或者逻辑假的结果 fmt 重新格式化指定文件的段落 fold 断开指定文件(默认是标准输入)较长的行,在屏幕上显示。 groups 显示一个用户所在的组 head 显示每个指定文件的前几行(默认是10)。 hostid 以16进制方式,显示当前主机的数字标志符。 hostname 显示或设置主机名 id 显示某个用户或者当前用户的真实和有效的 UID、GID 。 install 复制文件,设置它们的权限,如果可能还设置拥有它们的用户和组 join 合并两个文件的行 link 创建从指定文件到指定名称的硬链接 ln 创建文件之间的硬/软(符号)连接 logname 显示当前用户的登录名 ls 列出指定目录的所有内容。缺省是将文件和子目录按字母顺序排列。 md5sum 显示或者校验 MD5 校验码。 mkdir 建立目录,使用给定的参数作为目录名。 mkfifo 以给定的参数作为名字建立FIFO(又叫"命名管道")文件。 mknod 使用给出的文件名,建立一个设备节点,也就是:FIFO、字符特殊文件(special file)或者块特殊文件(special file)。 mv 根据所给参数的不同,把文件或者目录移动到另外的目录或者将其改名 nice 修改某个进程的调度优先级 nl 把每个指定文件的内容写到标准输出,在每行加上行号 nohup 使某个命令不被挂起,并将输出重定向到一个日志文件。 od 以数字方式显示指定文件的内容,默认为八进制。 paste 将字段连接在一起,在字段之间自动插入分割符,默认的分割符是 Tab 。 pathchk 检查文件名是否是有效的或者是可移植的 pinky 一个轻量级的 finger 客户端,用来得到某个用户的信息。 pr 将文件分成适当大小的页送到打印机 printenv 显示环境变量 printf 根据给定的参数格式化输出数据,与 C 语言中的该函数相似。 ptx 为指定的文件提供一个排序索引 pwd 显示当前工作目录 readlink 显示指定符号链接的值 rm 删除文件或者目录 rmdir 删除目录(目录必需为空) seq 以指定的步长输出一个数列 sha1sum 显示或校验 160 位的 SHA1 校验码 shred 安全删除一个文件,重写其占用的磁盘空间,使其无法恢复。 sleep 延迟一段时间 sort 对文件进行排序 split 把文件分成固定大小(字节或行数)的片断 stat 显示文件或者文件系统的状态 stty 改变和显示终端行的设置 sum 显示指定文件的校验和及块数 sync 刷新文件系统缓冲区,使磁盘和内存的数据同步。 tac 逆向显示指定的文
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值