命令功能:默认查询进程可用的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++ */