用户态进程管理的方方面面

五、系统平均负载,使用stress、mpstat、pidstat工具,找出平均负载升高的根源,3分,少一个截图扣1分,少1条心得扣1分

(一)系统平均负载

Load指标表示特定时间间隔内,系统有多少个正在运行的任务。包含:
①正在CPU上面运行的任务数量(运行状态)
②等待CPU调度运行的任务数量(不可中断状态)
③等待IO执行结果的任务数量(不可中断状态)

​ 根据工程经验,一般来说,当系统的Load指标值大于系统中总CPU核数的1.5~2倍时,表明系统负载较重,需要分析原因,采取措施降低Load指标值。否则可能产生系统卡顿的现象。如果系统的Load指标值大于系统中总CPU核数的3倍时,,表明系统负载非常严重。
注:若支持超线程技术,这里的总CPU核数 就换成 总逻辑CPU数

(二)工具说明:

1. stress

stress是Linux系统压力测试工具,可以对CPU、Memory、IO、磁盘进行压力测试。这里我们把它用作异常进程模拟平均负载升高的场景。

在这里插入图片描述

2. mpstat

mpstat可以查看所有cpu的平均负载,也可以查看指定cpu的负载。所以mpstat其实就是主要查看CPU负载的一个工具。是一款常用的多核CPU性能分析工具,用来实时查询每个CPU的性能指标,以及所有CPU的平均指标。

​ 语法:mpstat [ 选项 ] [ <时间间隔> [ <次数> ] ]

​ 选项:[ -P { <cpu_list> | ON | ALL } ]

​ 间隔时间:每次报告的间隔时间(秒)

​ 次数:显示报告的次数

3.pidstat

pidstat是一个常用的进程性能分析工具,用来实时查看进程的CPU,内存,IO,以及上下文切换等性能指标。

​ 语法:pidstat [ 选项 ] [ <时间间隔> [ <次数> ] ]

在这里插入图片描述

(三)实验

​ stress 消耗 CPU 资源的方式是通过调用 sqrt 函数计算由 rand 函数产生的随机数的平方根实现的,执行指令stress -c 4 产生 4 个这样的进程不断的进行计算:

在这里插入图片描述

​ 执行指令mpstat -P ALL 1

在这里插入图片描述

​ %usr表示用户所有使用的CPU百分比

​ %sys表示内核进程使用的 CPU 百分比

​ 从上图可以看出CPU几乎都是在用户态运行,运行时间接近99%,只能看出来CPU可能会出现严重负载的情况,但看不出来详细的系统平均负载情况,于是我执行了top命令:

在这里插入图片描述

​ 我这才发现了此时的CPU出现了严重负载的情况。于是我执行指令pidstat -u 1 对CPU出现严重负载的情况进行查明:

在这里插入图片描述

​ 由上图可知,CPU几乎全部的时间都在运行这4个stress进程,可见此时系统的高负载是由这4个stress进程导致的。

(四)心得体会

​ ①经过这一问的学习,我对stress、mpstat、pidstat工具有了系统性的认识,已经能够熟练的使用它们了

​ ②通过上述实验,我发现平均负载过高可能是CPU密集型进程导致的。

​ ③当发生CPU密集型进程导致的高负载的情况时,我们可以通过top命令查看此时的负载情况,然后利用pidstat命令找到导致发生高负载情况的进程,然后进行解决

六、参考P81页的代码,编写程序,父进程打印控制菜单,并接受命令(上面列出的命令至少5个),然后创建子进程,让子进程去处理任务,而父进程继续打印菜单并接受命令。说明调试过程以及新的体会,并给出截图,少一个命令扣1分,少1条心得扣1分

(一)程序

menu.c代码:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc, char * argv[]) {
	pid_t pid;
	char cmd;
	char * arg_psa[] = {"ps","-a",NULL};
	char * arg_psx[] = {"ps","-x",NULL};
	char * arg_stress[] = {"stress","-c","4","-t","100",NULL};
	char * arg_uptime[] = {"uptime",NULL};
	char * arg_pidstat[] = {"pidstat","-u","1","3",NULL};
	while(1) {
		printf("-----------------------------\n");
		printf("input a run 'ps -a' commend\n");
		printf("input x run 'ps -x' commend\n");
		printf("input s run 'stress -c 4 -t 100' commend\n");
		printf("input u run 'uptime' commend\n");
		printf("input p run 'pidstat -u 1 3' commend\n");
		printf("input q exit\n");
		cmd = getchar();					//接受输入字符
		getchar();
		if((pid = fork()) < 0) {			//创建子进程
			perror("fork error:");
			return -1;
		}
		if(pid == 0) {						//子进程
			switch(cmd) {
				case 'a':
						execve("/bin/ps",arg_psa,NULL);
						break;
				case 'x':
						execve("/bin/ps",arg_psx,NULL);
						break;
				case 's':
						execve("/usr/bin/stress",arg_stress,NULL);
						break;
				case 'u':
						execve("/usr/bin/uptime",arg_uptime,NULL);
						break;
				case 'p':
						execve("/usr/bin/pidstat",arg_pidstat,NULL);
						break;
				case 'q':
						break;
				default:
						perror("wrong cmd:\n");
						break;
			}
			exit(0);
		} else if(pid > 0) {			//父进程
			if(cmd == 'q')
				break;
		}
	}
	while(waitpid(-1,NULL,WNOHANG)>0);
	return 0;
}

运行结果:

在这里插入图片描述

进行调试:

​ 输入 a 显示一个终端的所有进程:

在这里插入图片描述

​ 输入x 显示没有控制终端的进程,同时显示各个命令的具体路径:

在这里插入图片描述

​ 输入 s 模拟平均负载升高的场景:

在这里插入图片描述

​ 输入 u 可以查看此时的平均负载情况:

在这里插入图片描述

​ 输入 p 查看每个进程使用CPU的情况:

在这里插入图片描述

​ 通过以上运行结果,我们可知可以借用此程序去模拟第五问中的实验。

(二)心得体会

​ ①个人感觉这程序其实是模拟了一个终端,我们可以在这里实现输入输出,可以自行的添加功能。

​ ②让我对fork系统调用有了更生动的认识

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值