目录
1.进程退出
2.孤儿进程
3.僵尸进程
#include
void exit(int status);
#include
void _exit(int status);
status参数:是进程退出时的一个状态信息。父进程回收子进程资源的时候可以获取到。
测试exit函数的程序:
#include
#include
#include
int main()
{
printf("hello\n"); //有\n
printf("world"); //无\n
exit(0);
}
运行结果:
测试_exit函数的程序:
#include
#include
#include
int main()
{
printf("hello\n"); //有\n
printf("world"); //无\n
_exit(0);
}
运行结果:
为什么两个输出结果有差别呢?
第一个printf语句带有“\n”,会刷新缓冲区。所以两个程序都输出了hello。
第二个printf语句没有“\n”,从第一个图可知exit函数会刷新缓冲区,_exit函数不会刷新缓冲区,所以第一个程序还会输出world,而第二个程序没有。
程序:
#include
#include
int main()
{
pid_t pid=fork();
if(pid>0)
{
printf("I am a parent process! pid=%d ppid=%d\n",getpid(),getppid());
}
else if(pid==0)
{
sleep(1);
printf("I am a child process! pid=%d ppid=%d\n",getpid(),getppid());
}
for(int i=0;i<3;i++)
{
printf("i=%d pid=%d\n",i,pid);
}
return 0;
}
运行结果:
当在终端中执行可执行程序中,会默认切换到该程序执行,这也就是为什么终端中会显示程序中输出的内容。
其中,程序中的父进程的父进程的id 12145为当前终端,可以进行验证:
因为终端是程序中父进程的父进程,所以,终端知道程序中父进程什么时候运行结束,在程序中父进程运行结束之后又切换回终端,所以会显示上上个图中里面红框圈起来的部分。但是终端不知道父进程还有没有运行结束的子进程,所以后面会接着显示程序中子进程的内容。为什么子进程输出的内容也会显示在当前终端呢?因为fork后,子进程和父进程的文件描述符表是一样的(读时共享),代表同一个终端。
孤儿进程会由进程ID为1的init进程收养,由init完成孤儿进程的资源释放工作。孤儿进程是没有危害的。
程序:
#include
#include
int main()
{
pid_t pid=fork();
if(pid>0)
{
while(1)
{
printf("I am a parent process! pid=%d ppid=%d\n",getpid(),getppid());
sleep(5);
}
}
else if(pid==0)
{
printf("I am a child process! pid=%d ppid=%d\n",getpid(),getppid());
}
for(int i=0;i<3;i++)
{
printf("i=%d pid=%d\n",i,getpid());
}
return 0;
}
运行结果:
用ps aux查看进程信息,如下图:
从图中可以看出,子进程12216为僵尸进程。因为子进程已经运行结束了,父进程没有对子进程的内核区数据进行回收,且父进程一直在运行。僵尸进程一直占用系统资源,所以要想办法解决。
解决办法之一:
让父进程结束运行:
因为父进程结束后,子进程(即僵尸进程)的父进程会变为init进程,init进程会对僵尸进程的资源进行回收。
实际上,有时候程序要一直运行,不能用ctrl+c将其杀死。
解决办法之二:
父进程中调用wait函数或waitpid函数对子进程的资源进行回收。这种方法在后面讲。
参考:牛客网 C++高薪求职项目《Linux高并发服务器开发》2.7进程退出、孤儿进程、僵尸进程
专属优惠链接:
https://www.nowcoder.com/courses/cover/live/504?coupon=AvTPnSG