3.编写实验程序task3.c创建一个子进程,要求在父进程中不用wait函数对子进程做任何处理,让子进程比父进程先结束,成为一个僵尸进程,并在程序中使用ps命令打印出僵尸进程的信息。

参考linux 进程管理笔记
在这里插入图片描述
他们二个的区别:

一、 僵尸进程

僵尸进程: 一个父进程利用fork创建子进程,如果子进程退出,而父进程没有利用wait 或者 waitpid
来获取子进程的状态信息,那么子进程的状态描述符依然保存在系统中。

二、孤儿进程

孤儿进程:一个父进程退出,
而它的一个或几个子进程仍然还在运行,那么这些子进程就会变成孤儿进程,孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集的工作


僵尸进程将会致使资源浪费,而孤儿进程则不会。


ps:打印信息

在这里插入图片描述
见笔记、

system("ps -o pid,ppid,state,tty,command");

“”表示执行命令
ps -o 在这里插入图片描述
指定字段
pid ppid

其中USER表示启动进程的用户,pid、TTY、TIME这些选项的含义与ps默认输出的相同,其余各项代表的含义分别如下:

%CPU表示进程占用CPU的时间与进程已运行时间的百分比,一般情况下这个数值不会达到100%。
·%MEM表示进程的物理内存集与系统物理内存的百分比。VSZ表示虚拟内存集,即进程占用虚拟内存的大小(1024字节为一个单位)。
RSS表示驻留集大小,即进程使用的物理内存的大小(1024字节为一个单位)。
STAT表示进程当前的状态。D表示不可中断的睡眠态,R表示运行态,S表示可中断的睡眠态,T表示停止,Z表示低死态(即户进程)。状态之后的表示该进程是会话进程中的首进程。
COMMAND即CMD,表示启动该进程的命令
打印出来


总代码:

#include <stdio.h>
#include "unistd.h"
#include "stdlib.h"
#include "sys/types.h"
int main(int argc, char const *argv[])
{
	pid_t pid;
	pid = fork();							//调用fork()函数创建子进程
	if (pid == -1){
		perror("fork error");
		exit(1);
	}
	else if (pid==0)
	{
		printf("i am child process. i am exiting.\n");
		exit(0);
	}
	else if(pid>0) 
	{
		printf("i am a father process. i will sleep two seconds\n");
		sleep(2);
	}

	system("ps -o pid,ppid,state,tty,command");
	printf("father process is exiting.\n");
	return 0;
}

效果:
在这里插入图片描述


回收子进程

4.对task3.c程序进行修改,回收子进程,并打印出进程信息。

#include <stdio.h>
#include "unistd.h"
#include "stdlib.h"
#include "sys/types.h"
int main(int argc, char const *argv[])
{
	int status;
	pid_t pid,w;
	pid = fork();							//调用fork()函数创建子进程
	if (pid == -1){
		perror("fork error");
		exit(1);
	}
	else if (pid==0)
	{
		printf("Child process:pid=%d\n", getpid());
		exit(0);
	}
	else if(pid>0) 
	{
		w=wait(&status);
		if (WIFEXITED(status)){
			printf("Child process pid=%d exit normally.\n", w);
			printf("Return Code:%d\n", WEXITSTATUS(status)); 
		}
		else
			printf("Child process pid=%d exit abnormally.\n", w);

	}

	system("ps -o pid,ppid,state,tty,command");
	printf("father process is exiting.\n");
	return 0;
}

关于WEXITSTATUS和WIFEXITED
和w
参考linux 进程管理笔记

当然,wait()函数中的参数可以不为空。若status不为空,wait()函数会获取子进程的退出状态,退出状态被存放在exit()函数参数status的低八位中。使用常规方法读取比较麻烦,因此Linux系统中定义了一组用于判断进程退出状态的宏函数,其中最基础的是WIFEXITED()和WEXITSTATUS(),它们的参数与wait()函数相同,都是一个整型的status。宏函数的功能分别如下:
(1)WIFEXITED(status):用于判断子程序是否正常退出,若是,则返回非0值;否则返回0。

(2)WEXITSTATUS(status):WEXITSTATUS()通常与WIFEXITED()结合使用若WIFEXITED返回非0值(即正常退出),则使用该宏可以提取子进程的返回值。
在这里插入图片描述

效果:
在这里插入图片描述

Logo

更多推荐