#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main()
{
int n;
int i;
char *s;
pid_t pid=fork();
assert(pid!=-1);
if(pid == 0)
{
n=2;
s="child";
}
else
{
n=5;
s="parent";
}
for(i=0;i<n;i++)
{
printf("%d,%s\n",getpid(),s);
sleep(1);
}
return 0;
}
在父程序中用于判断子程序是否结束
僵尸进程子进程提前于父进程结束,造成无法清理掉pcb和其他系统消耗造成pid的长时间占用(如上图)
如果父进程异常结束时就成了一个孤儿进程交个pid=1 的init作为父进程进行管理收尸;
三种处理方式
⒈父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起问题父进程在wait处会阻塞如果父进程很忙会造成一系列
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
int main()
{
signal(SIGCHLD,fun);
char *p=NULL;
pid_t pid=fork();
assert(pid!=-1);
int n=0;
if(pid==0)
{
p="child";
n=10;
}
else
{
p="parent";
n=20;
}
int i=0;
for(;i<n;i++)
{
printf("%s\n",p);
sleep(1);
}
if(pid!=0)
{
wait();
}
return 0;
}
⒉ 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收。
第二种代码(只要在父进程收到子进程结束的信号时就去处理该信号)
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
void fun(int sig)
{
printf("sig=%d\n",sig);
wait();
signal(SIGCHLD,SIG_DFL);//回复默认
}
int main()
{
signal(SIGCHLD,fun);
char *p=NULL;
pid_t pid=fork();
assert(pid!=-1);
int n=0;
if(pid==0)
{
p="child";
n=10;
}
else
{
p="parent";
n=20;
}
int i=0;
for(;i<n;i++)
{
printf("%s\n",p);
sleep(1);
}
return 0;
}
⒊ 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD,SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
int main()
{
signal(SIGCHLD,SIG_IGN);
char *p=NULL;
pid_t pid=fork();
assert(pid!=-1);
int n=0;
if(pid==0)
{
p="child";
n=10;
}
else
{
p="parent";
n=20;
}
int i=0;
for(;i<n;i++)
{
printf("%s\n",p);
sleep(1);
}
return 0;
}
还就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。相比与第一种的好处就是父进程不用等因为子进程在父进程运行时很快就结束了;
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
int main()
{
char *p=NULL;
pid_t pid=fork();
assert(pid!=-1);
int n=0;
if(pid==0)
{
pid_t pid=fork();
if(pid==0)
{
p="child";
n=5;
}
else
{
printf("%d",getpid());
exit(0);//使他提前结束孙进程交给pid=1;
}
}
else
{
p="parent";
n=20;
}
wait(NULL);
int i=0;
for(;i<n;i++)
{
printf("pid=%d,%s\n",getpid(),p);
sleep(1);
}
return 0;
}