流程资源


进程需要一定的资源(例如CPU和内存)来执行任务。现在我们通过相关的命令和系统调用来了解资源利用和监控的信息。此外,默认情况下每个进程对资源都有一定的限制,如果需要,可以增强这些限制以满足应用程序的要求。

以下是使用命令的基本系统或进程资源信息 -

顶层命令

$ top

top命令持续显示系统资源的使用情况。如果任何进程使系统处于某种挂起状态(消耗更多的 CPU 或内存),则可以记录该进程信息并采取适当的操作(例如终止相关进程)。

ps 命令

$ ps

ps 命令提供有关所有正在运行的进程的信息。这有助于监视和控制过程。

vmstat 命令

$ vmstat

vmstat 命令报告虚拟内存子系统的统计信息。它报告进程信息(等待运行、Hibernate、可运行进程等)、内存(空闲、已用等虚拟内存信息)、交换区、IO设备、系统信息(中断次数、上下文切换)和 CPU(用户、系统和空闲时间)。

lsof 命令

$ lsof

lsof 命令打印所有当前正在运行的进程(包括系统进程)的打开文件列表。

getconf 命令

$ getconf –a

getconf 命令显示系统配置变量信息。

现在,让我们看一下相关的系统调用。

  • 系统调用 getrusage(),它提供有关系统资源使用情况的信息。

  • 与访问和设置资源限制相关的系统调用,即 getrlimit()、setrlimit()、prlimit()。

系统资源使用调用

#include <sys/time.h>
#include <sys/resource.h>

int getrusage(int who, struct rusage *usage);

系统调用 getrusage() 返回有关系统资源使用情况的信息。这可以包括有关自身、子级或使用“who”变量的标志 RUSAGE_SELF、RUSAGE_CHILDREN、RUSAGE_THREAD 的调用线程的信息。调用后,返回结构体rusage中的信息。

成功时此调用将返回“0”,失败时将返回“-1”。

让我们看看下面的示例程序。

/* 文件名: sysinfo_getrusage.c */

#include<stdio.h>
#include<sys/time.h>
#include<sys/resource.h>

void main(void) {
   struct rusage res_usage;
   int retval;
   retval = getrusage(RUSAGE_SELF, &res_usage);
   if (retval == -1) {
      perror("getrusage error");
      return;
   }
   printf("Details of getrusage:\n");
   printf("User CPU time (seconds) is %d\n", (int)res_usage.ru_utime.tv_sec);
   printf("User CPU time (micro seconds) is %d\n", (int)res_usage.ru_utime.tv_usec);
   printf("Maximum size of resident set (kb) is %ld\n", res_usage.ru_maxrss);
   printf("Soft page faults (I/O not required) is %ld\n", res_usage.ru_minflt);
   printf("Hard page faults (I/O not required) is %ld\n", res_usage.ru_majflt);
   printf("Block input operations via file system is %ld\n", res_usage.ru_inblock);
   printf("Block output operations via file system is %ld\n", res_usage.ru_oublock);
   printf("Voluntary context switches are %ld\n", res_usage.ru_nvcsw);
   printf("Involuntary context switches are %ld\n", res_usage.ru_nivcsw);
   return;
}

编译和执行步骤

Details of getrusage:
User CPU time (seconds) is 0
User CPU time (micro seconds) is 0
Maximum size of resident set (kb) is 364
Soft page faults (I/O not required) is 137
Hard page faults (I/O not required) is 0
Block input operations via file system is 0
Block output operations via file system is 0
Voluntary context switches are 0
Involuntary context switches are 1

现在让我们看看与访问和设置资源限制相关的系统调用。

#include <sys/time.h>
#include <sys/resource.h>

int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlimit *old_limit);

系统调用getrlimit()通过输入需要的资源(如 RLIMIT_NOFILE、RLIMIT_NPROC、RLIMIT_STACK 等)来获取结构体 rlimit 中的资源限制。

系统调用setrlimit()将 rlimit 结构中提到的资源限制设置为限制范围内。

系统调用prlimit()用于多种目的,例如检索当前资源限制或将资源限制更新为新值。

结构 rlimit 包含两个值 -

  • 软限制- 电流限制

  • 硬限制- 可以扩展的最大限制。

RLIMIT_NOFILE - 返回此进程可以打开的文件描述符的最大数量。例如,如果它返回 1024,则该进程具有从 0 到 1023 的文件描述符。

RLIMIT_NPROC - 可以为该进程的用户创建的最大进程数。

RLIMIT_STACK - 该进程的堆栈段的最大大小(以字节为单位)。

所有这些调用都会在成功时返回“0”,在失败时返回“-1”。

让我们考虑以下使用 getrlimit() 系统调用的示例。

/* 文件名: sysinfo_getrlimit.c */

#include<stdio.h>
#include<sys/time.h>
#include<sys/resource.h>

void main(void) {
   struct rlimit res_limit;
   int retval;
   int resources[] = {RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_STACK};
   int max_res;
   int counter = 0;
   printf("Details of resource limits for NOFILE, NPROC, STACK are as follows: \n");
   max_res = sizeof(resources)/sizeof(int);
   while (counter < max_res) {
      retval = getrlimit(resources[counter], &res_limit);
      if (retval == -1) {
         perror("getrlimit error");
         return;
      }
      printf("Soft Limit is %ld\n", res_limit.rlim_cur);
      printf("Hard Limit (ceiling) is %ld\n", res_limit.rlim_max);
      counter++;
   }
   return;
}

编译和执行步骤

Details of resource limits for NOFILE, NPROC, STACK are as follows: 
Soft Limit is 516
Hard Limit (ceiling) is 516
Soft Limit is 256
Hard Limit (ceiling) is 256
Soft Limit is 33554432
Hard Limit (ceiling) is 33554432

让我们考虑另一个使用 getrlimit() 系统调用但现在使用 prlimit() 系统调用的示例。

/* 文件名: sysinfo_prlimit.c */

#include<stdio.h>
#include<unistd.h>
#include<sys/time.h>
#include<sys/resource.h>

void main(void) {
   struct rlimit res_limit;
   int retval;
   int resources[] = {RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_STACK};
   int max_res;
   int counter = 0;
   printf("Details of resource limits for NOFILE, NPROC, STACK using prlimit are as follows: \n");
   max_res = sizeof(resources)/sizeof(int);
   while (counter < max_res) {
      retval = prlimit(getpid(), resources[counter], NULL, &res_limit);
      if (retval == -1) {
         perror("prlimit error");
         return;
      }
      printf("Soft Limit is %ld\n", res_limit.rlim_cur);
      printf("Hard Limit (ceiling) is %ld\n", res_limit.rlim_max);
      counter++;
   }
   return;
}

编译和执行步骤

Details of resource limits for NOFILE, NPROC, STACK using prlimit are as follows: 
Soft Limit is 516
Hard Limit (ceiling) is 516
Soft Limit is 256
Hard Limit (ceiling) is 256
Soft Limit is 33554432
Hard Limit (ceiling) is 33554432