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++ */

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值