孤儿进程与僵尸进程
2021/5/22 7:27:39
本文主要是介绍孤儿进程与僵尸进程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
孤儿进程:
父进程先死了,子进程被init进程领养,即子进程的父进程pid变成了1
这个子进程就叫孤儿进程
僵尸进程:
子进程死了,但是父进程没有回收子进程的资源(子进程的资源必须由父进程回收,操作系统不会自动回收)
任何进程都会存在僵尸进程阶段,只不过有些及时被回收了
因为僵尸进程是已经死掉的进程,因此用kill没办法回收僵尸进程
子进程回收
一个进程终止时关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留的,内核在其中保留一些信息:
如果是正常终止,则保留着退出状态
如果是异常终止,则保存导致该进程终止的信号是哪个
终止进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除掉这个进程
wait函数
作用:
1 阻塞等待,即在父进程中调用的wait会一直等待子进程死亡然后再进行回收
2 回收子进程资源
3 查看死亡原因
pid_t wait(int *status)
status: 是一个传出参数,即定义一个整型变量,然后把该整型变量传进wait函数中就行,然后操作系统会给该形参复制,从而获取进程的结束状态
返回值:如果成功,返回已经终止的子进程的pid,如果失败返回-1
int main(){ pid_t pid = fork(); if(pid == 0){ cout<<"孩子"<<endl; sleep(2); } else if(pid > 0){ cout<<"父进程"<<endl; int status; // 整型数,用来接收子进程终止状态 pid_t wpid = wait(&status); // 如果子进程不死,则父进程会停留再这一行语句阻塞等待,如果不看终止状态的话,直接传入NULL就行,不用特地传个整型数 if(WIFEXITED(status)){ cout<<"退出状态"<<WEXITEDSTATUS(status)<<endl; } if(WIFSIGNALED(status)){ cout<<"孩子被几号信号杀死?"<<WTERMSIG(status)<<endl; } cout<<"孩子die"<<endl; while(1){ sleep(1); } } return 0; }
子进程死亡原因可以把status传入几个宏来获取
正常死亡:WIFEXITED(status) == true, 代表正常死亡,WEXITSTATUS(status)得到退出状态(退出状态一般指的是子进程的返回值,比如return 101, 那就是101,exit(544),那就是544)
非正常死亡:WIFSIGNALED(status) == true, 代表非正常死亡,WTERMSIG得到是第几号信号将其杀死的
waitpid函数
pid_t waitpid(pie_t pid, int *status, int options)
返回值:
成功:返回清理掉的子进程ID
失败:-1(当当前进程没有子进程的时候,回收失败)
如果设置了WNOHANG,那么会返回0
参数pid:
>0 回收指定ID的子进程
-1 回收任意子进程
0 回收进程组ID与当前父进程的进程组ID相同的子进程,这说明了一个问题,虽然一般情况下子进程的进程组ID等于父进程的进程组ID,但是子进程的进程组ID也是可以不等于其父进程的进程组ID的,这种情况下就不能用pid=0来回收该进程了,所以还是用pid=-1比较好
-1 回收指定进程组内的任何子进程,这个进程组的组ID就是pid的绝对值,这意味着有多个子进程其组ID相同,但是与父进程的组ID不同,但血浓于水,父进程还是要回收他们
options:
可以为0或者WNOHANG
0: 跟wait一样,waitpid会发生阻塞等待
WNOHANG: 如果没有子进程退出,会立刻返回
回收多个子进程
wait和waitpid一次都是只能回收一个子进程,如果要回收多个子进程,可能就要用一个循环依次回收了
现在给出waitpid回收逻辑
if(i == 5){ // 父进程的逻辑 while(1){ pid_t wpid = waitpid(-1, NULL, WNOHANG); if(wpid == -1){ // 说明已经没有子进程 break; } else if(wpid > 0){ cout<<"回收子进程ID"<<wpid<<endl; } } }
这篇关于孤儿进程与僵尸进程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-04TiDB 资源管控的对撞测试以及最佳实践架构
- 2024-07-03万字长文聊聊Web3的组成架构
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现