赞
踩
进程只要是收到什么信号,则表明这个进程是异常退出的
进程等待的作用:
- 父进程在它的执行代码中调用进程等待的方法,等待子进程退出,防止子进程变成僵尸进程
- 实质:
子进程保存了自己的进程退出码给父进程,父进程获取了退出码后才能释放子进程资源
pid_t wait (int* status)
- 作用:等待当前调用者的任意一个子进程退出,获取返回值释放资源
多个子进程退出只能处理一个- 函数参数是输出型参数,通过形参修改实参
将wait函数内部计算的某个结果通过status变量返回给调用者- 返回值
成功:返回处理的退出的子进程的pid
失败:返回-1- 阻塞:为了完成一个功能发起了一个调用,但是这个调用完成条件不具备,则接口一直等待不返回
- 非阻塞接口:为了完成一个功能发起了一个调用,但是这个调用完成条件不具备,则立即报错返回
status是一个指针类型占四个字节,但是实际中只使用到后16位
- 退出码 + coredump标志位 + 退出信号
- 高8位表示退出码;
- 1位的coredump标志位
翻译过来是核心转储,程序异常退出,保存程序运行程序,一般是关闭的- 低7位的退出信号
退出码:程序正常退出时用到
- main函数的return返回时,return后的数字就是退出码
- exit和_exit中的参数就是退出码
coredump标志位,退出信号是程序异常退出时用到:
- 为0表示该进程在退出时没有内存镜像文件的产生(也就是说没有coredump产生)
- 为1则有镜像文件产生,当前程序退出异常
退出信号:进程异常退出时收到的几号信号
产生coredump文件不能判断进程是否正常退出的原因:
- 程序在运行时崩溃(例如解引用空指针),该进程会收到崩溃信号;
- 该信号可能会让进程产生一个coredump文件,这个文件并不是收到崩溃信号就一定会产生。
- 是否产生coredump文件取决于:
磁盘硬限制,空间大小不足;
系统的软限制,进程可以产生coredump文件但是系统不让其产生
- 一个进程在异常退出时,如果收到了某些信号,系统为了方便用户调试在进程退出时触发coredump机制
这个机制叫核心转储- 外部问题和代码没关系,而3468 11信号是程序内部的问题导致进程出现终止
- 对应的标志位会被置1,并且会在当前路径下生成一个core.xxxx文件(xxxx是对应的进程号)
- 核心转储的本质coredump会把进程在运行中各种数据和代码信息转储到磁盘上方便调试
直接gdb后打印 core-file core.xxx就定位到错误发生的行数了
异常退出是因为收到了特定的信号,通过status右移7位得到
发信号的过程在信号部分讲解
- 父进程一旦调用wait函数后,当子进程没有退出前,wait函数是不会返回;
- 父进程调用wait函数,wait函数就压到父进程的栈帧上,子进程没有退出,父进程栈帧是不会销毁的,也就是说wait函数不会出栈返回
- 程序正常退出的时候,也就是经过return或者exit退出,都是设置了退出码
- 但是如果程序是运行途中,异常崩溃的,则保存的退出码根本就没有意义,因为根本就没有进行设置
- 异常信号值,作用就是保存异常退出的原因,为0表示程序正常退出,!0则表示异常退出
- 所以先取信号低七位值是否是0,是0表示正常退出,再取高八位的退出码
1.判断是否有退出信号
- 正常退出时,退出信号7位全=0;异常退出,退出信号>0;
- 所以
int _status=wait(&status);
status & 0xfff ffff;
,等于0正常退出,>0异常退出
2.判断coredump标志位
(ststus >> 7) & 0x1;
3.判断退出码
(ststus >> 8) & 0xff;
也就是按位与上八个一- 或者两个宏
4.退出信号
ststus & 0x7f
把进程从运行队列中拿出来放到等待队列中,在等待一个条件
这是在等待软件
阻塞概念:当调用结果返回之前,当前的执行流会被挂起,并在得到结果之后返回
- 或者说:调用结果返回前,当前线程会被挂起,并在得到结果之后返回
- 例如:父进程被wait函数阻塞,父进程就会被挂起,必须等到子进程结束后才能返回
- 使用上述代码,只需给父进程处加一个死循环即可;
- 运行后通过pstack+父进程进程号查看父进程栈帧;
父进程一直在wait,并没有返回;
对阻塞和非阻塞理解:
1.子进程一种在运行;
- 阻塞:父进程等待子进程运行完后退出;这就是阻塞
- 非阻塞:父进程不等子进程运行是否运行完毕就退出,这样可能会导致孤儿进程;这就是非阻塞
2.子进程已退出
- 阻塞:父进程正常退出
- 非阻塞:父进程正常退出
对于两种非阻塞的情况,父进程都是直接退出,但是两种情况父进程退出后,一种正常一种不正常
返回值:
等待成功,返回子进程退出码
非阻塞等待,没有等到子进程则返回0,等待失败-1,成功返回子进程退出码
wait函数的实现是调用waitpid函数实现
- 非阻塞模式下waitpid函数返回是没有等待子进程的;
- waitpid函数在非阻塞模式下只调用一次并且也没等待到子进程退出,再不去调用该函数;
- 等到子进程退出后子进程就会变成僵尸进程;
- 所以在非阻塞模式下需要搭配循环;
使用非阻塞,父进程可以在等待的同时做别的事情
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。