Linux详解:进程等待

进程等待

等待的必要性

  • 子进程退出,父进程不进行回收的话,就可能造成僵尸进程,进而造成内存泄露

  • 如果进程进入了僵尸状态,kill也杀不掉这个进程。因为谁也杀不死一个已经死去的进程

  • 父进程派给子进程的任务完成的如何,使用者应该直到结果。子进程的任务是完成了还是未完成。

  • 父进程通过进程等待(wait)的方式,回收子进程的资源,获取子进程的退出信息

  • 父进程通过wait的方式,回收子进程的资源

    子进程的退出信息,保存在子进程的pcb中。

进程等待的方法

#include<sys/types.h>
#incldue<sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);

wait

pid_t wait(int *status);
  • 默认进行阻塞等待,子进程没有退出,父进程就一直等待。
  • 等待父进程的任意一个子进程退出。
  • 返回值:
    • >0:等待成功,返回值是等待子进程的pid
    • <0:等待失败
  • 参数:输出型参数,获取子进程的退出状态,如果不关心则可以设置为NULL

frok之后,父子进程谁先运行,不确定,是由操作系统的调度器运行。但是谁最后退出是确定的,父进程一定要最后退出,因为要等待子进程运行结束之后回收子进程。

waitpid

pid_t waitpid(pid_t pid, int *status, int options);
  • 返回值:
    • >0:等待成功,返回值是等待子进程的pid
    • <0:等待失败
  • 参数
    • pid
      • pid=-1,等待人一个子进程,与wait等效
      • pid>0,等待其进程id与pid值相等的子进程
    • status:输出型参数,获取子进程的退出状态,如果不关心则可以设置为NULL
    • options:0、非阻塞

获取子进程status

  • wait和waitpid,都有一个status参数,这个参数是一个输出型参数,由操作系统进行填充
  • 如果传递NULL,表示不关心子进程的退出状态信息
  • 如果不是NULL,则操作系统会根据该参数,将子进程的退出信息反馈给父进程
  • status不能简单的当作整形来看待,应该当成位图来看,只考虑status的低16位。
status:0000 0000 0000 0000 0000 0000 0000 0000

信号编号进程退出码表示状态
00没有异常,结果正确
!00出现异常,退出码无意义
0!0没有异常,结果错误
!0!0出现异常,退出码无意义
0~7,进程出现异常,收到的信号编号
9~15,进程正常结束的退出码

信号编号:status&0x7F
退出码:(status >> 8)& 0xFF

status:

  • WIFEXITED(status):若为正常终止子进程返回的状态,则为真。(查看进程是否正常退出)。判定当前进程的退出信号是否为0,为0就为真,不为0就是假。
  • WEXITSTATUS(status):若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)。

因为进程具有独立性,所以父子无法直接互相修改对方的数据之后,让对方看到。

因为读取子进程退出信息,本质上是读取内核数据,所以需要调用系统接口。

#include<sys/types.h>
#incldue<unistd.h>
#include<sys/wait.h>
int main()
{
	pid_t id = fork();
	if(id == 0)
	{
		int cnt = 5;
		while(cnt)
		{
			printf("child is running, pid:%d, ppid:%d",getpid(),getppid());
			sleep(1);
			cnt--;
		}
		exit(0);
	}
	int status = 0;
	pid_t rid = waitpid(id,&status,0);
	if(id>0)
	{
		printf("wait success,rid:%d , status:%d, exitsigno:%d, exitcode    :%d\n",rid,status,(status&0x7F),((status>>8)&0xFF));
	}
}

阻塞等待 与 非阻塞等待

父进程阻塞等待,当子进程还在执行时,没有返回,父进程会将自己设置为阻塞状态,一直等待着子进程结束回收。

非阻塞等待,父进程检查子进程是否返回,如果子进程没有返回,不进行等待,父进程立刻返回,返回值为0。如果子进程已经返回,则返回子进程的id。

WNOHANG:若pid指定的子进程没有结束,则waitpid()函数返回0,不予等待,若正常结束,则返回该子进程的id。

单次调用:非阻塞

基于非阻塞的轮询访问

机器宕机了,操作系统没有反应 – hang住了

  • 16
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

排骨炖粉条

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值