父进程调用wait函数究竟对子进程做了什么?

heartgoon2010 2011-07-13 11:34:18
父进程创建的子进程退出后,如果父进程不调用wait函数回收子进程的结束信息,子进程就会变成僵尸进程。
那么父进程调用wait函数究竟对子进程做了什么呢?希望高手帮忙解答,谢了
...全文
866 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
钱国正 2011-08-25
  • 打赏
  • 举报
回复
ding
jialejiahi 2011-08-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 threeleafzerg007 的回复:]
如果子进程成为僵尸进程:
1. 他的PID还占据着,意味着海量的子进程会占据满进程表项,会使后来的进程无法fork.
2. 他的内核栈无法被释放掉(1K 或者 2K大小),为啥会留着他的内核栈,因为在栈的最低端,有着thread_info结构,它包含着 struct_task 结构,这里面包含着一些退出信息。

这样你就知道父进程的wait主要干嘛了吧。
[/Quote]
这才是wait和waitpid的真正原因。
hejunw 2011-08-23
  • 打赏
  • 举报
回复
wait函数是使父进程阻塞,直到任意的一个子进程结束或者父进程接到一个指定的信号为止,如果该父进程没有子进程或者是它的子进程已经结束,则wait函数会立即返回.
pid_t wait(int *status); // 等待子进程的结束,同时接受子进程退出时间的状态,子进程在退出的时间发送给父进程一个sign的信号,告诉父进程自己已经结束,此时父进程在调用wait函数进行收回资源.
如果父进程在子进程之前先结束,那么子进程将成为一个孤儿进程,此时的子进程已经是处于僵死状态,占用系统资源,经过一段时间片,init将会收回这些孤儿进程,然后进行处理!
牛晨光 2011-07-21
  • 打赏
  • 举报
回复
取走子进程退出后的状态信息,CPU使用时间等。取走后内核就会把此僵尸进程释放掉!
WilliamKyle 2011-07-18
  • 打赏
  • 举报
回复
内核的源码应该会有这个函数的内容吧。
yy15861898196 2011-07-17
  • 打赏
  • 举报
回复
子进程变成僵尸进程,是因为父进程还没有执行完,没有替子进程收尸。而wait并不是用来收尸的,只是防止父进程先于子进程退出,父进程先退出,会使子进程成为孤儿进程,这时候子进程的收尸就由1号init进程来回收。如果想解决僵尸进程,可以去百度一下,这里提供一种信号的方法~
#include<stdarg.h>
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>

extern char **environ;

void pid_printf(char *format,...)//自定义printf,在每行输出前插入进程ID
{
va_list ap;
va_start(ap,format);
printf("%d:",getpid());//每行前插入
vprintf(format,ap);
}

void signal_handler(int signo)//收到信号后的处理fun
{
int ret;
pid_t pid_c;
switch(signo)
{
case SIGCHLD:
pid_c=wait(&ret);//使进程睡眠,直到它的一个子进程退出时唤醒
//pid_t wait(int *status) 返回值是退出的子进程的pid , status是子进程退出的状态信息
//还有一个是pid_t waitpid(pid_t pid,int *status,int options)
pid_printf("Child process PID = %d return %d.\n",pid_c,ret);
break;
case SIGUSR2:
pid_printf("Signal SIGUSR2 received\n");
break;
default:
pid_printf("Signal %d reveived.\n",signo);
break;
}

}
int main(int argc,char **argv)
{
pid_t pid;
signal(SIGCHLD,signal_handler);//捕捉SIGCHLD信号
signal(SIGUSR2,signal_handler);//捕捉SIGUSR2信号
pid=fork();
if(pid==0)
{
pid_printf("Child process send signal SIGUSR2 to parent proess.\n");

kill(getppid(),SIGUSR2);//发送信号SIGUSR2给父进程
//int kill(pid_t pid,int sig)
//pid>0 给pid的进程发信号 , pid=0全同一进程组所有进程发信号,
//pid<-1给其它的进程组为(-pid)的发信号, pid=-1给除自身之外的>1的进程发信号

pid_printf("Child process will exit with status 0.\n");
exit(0);
}else if(pid!=-1)
{
while(1)sleep(1);
}else
{
pid_printf("There was a error with fork() !\n");
}

return 0;
}


wzb56 2011-07-17
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 wyjq395 的回复:]
我和楼主有同样的疑问,查了下百度百科以及楼上各位的解释得出下面理解:
首先僵尸进程是死了之后没人为它收尸的进程。
如果父进程比子进程先死,1号进程回成为该子进程的父进程,并在它死后为它收尸,它不会成为僵尸。
但是父进程健在而没调用wait等待,则父进程无法知道子进程的状态,无法为子进程收尸,子进程没人收尸就变僵尸了。
所以wait等待子进程的状态变化,并获取相关信息,而收尸的是父进程不是w……
[/Quote]

楼上,说的很好!
个人认为: wait 能够起到防止父进程先于子进程死亡的作用。既然父进程创建了子进程,一般来讲,以期对子进程进行完全控制(包括子进程结束后的状态),可以起到同步的作用。但也有例外,shell子程序一般来讲都是父进程创建后,就把控制权完全交给了shell子程序,自己死亡。shell子程序结束后,正如楼上所说由1号进程回收。
woya321 2011-07-14
  • 打赏
  • 举报
回复
旁听着飘过
threeleafzerg007 2011-07-14
  • 打赏
  • 举报
回复
如果子进程成为僵尸进程:
1. 他的PID还占据着,意味着海量的子进程会占据满进程表项,会使后来的进程无法fork.
2. 他的内核栈无法被释放掉(1K 或者 2K大小),为啥会留着他的内核栈,因为在栈的最低端,有着thread_info结构,它包含着 struct_task 结构,这里面包含着一些退出信息。

这样你就知道父进程的wait主要干嘛了吧。
谭海燕 2011-07-14
  • 打赏
  • 举报
回复
父进程创建子进程,然后子进程通过execl簇函数载入程序块。父进程做他自己的事情。但是。父进程不能在子进程结束之前自己结束,因为这样子进程就成了孤儿了。这样你就失去了对子进程的控制。最重要的就是资源了,子进程的资源需要父进程去获得子进程的状态,如果确定子进程已经的确完成了使命,那么他所拿到的资源就可以释放了。父进程也就知道子进程的活动。
昵称很不好取 2011-07-14
  • 打赏
  • 举报
回复
wait只是查看子进程的状态,如果子进程还在运行就阻塞自己,等子进程运行完毕再接着运行,假如一件事情分为三步,子进程完成第二步,这样父进程等待子进程完成第二步之后才开始完成第三步,也算保持了一种同步
heartgoon2010 2011-07-14
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 feiyinzilgd 的回复:]
获取子进程状态然后释放资源。。。
[/Quote]
能具体一点吗。。。
谭海燕 2011-07-14
  • 打赏
  • 举报
回复
获取子进程状态然后释放资源。。。
heartgoon2010 2011-07-14
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 csusuntao 的回复:]
Linux man:
wait for state changes in a child of the calling process, and obtain information about the child whose state has changed.
等待子进程的状态变化,并获取相关信息。

The wait() system call suspends execution……
[/Quote]
那父进程调用wait函数跟不调用wait函数会有什么不同呢?
换句话说,子进程结束的时候,父进程回收其结束信息与不回收其结束信息有什么不同,不能仅仅是知不知道子进程退出原因的区别吧,愿求详解。。。
wyjq395 2011-07-14
  • 打赏
  • 举报
回复
我和楼主有同样的疑问,查了下百度百科以及楼上各位的解释得出下面理解:
首先僵尸进程是死了之后没人为它收尸的进程。
如果父进程比子进程先死,1号进程回成为该子进程的父进程,并在它死后为它收尸,它不会成为僵尸。
但是父进程健在而没调用wait等待,则父进程无法知道子进程的状态,无法为子进程收尸,子进程没人收尸就变僵尸了。
所以wait等待子进程的状态变化,并获取相关信息,而收尸的是父进程不是wait。

父进程是如何为子进程收尸,释放子进程资源的呢?我也不清楚,应该是OS的事情了。
poor_coder 2011-07-13
  • 打赏
  • 举报
回复
Linux man:
wait for state changes in a child of the calling process, and obtain information about the child whose state has changed.
等待子进程的状态变化,并获取相关信息。

The wait() system call suspends execution of the calling process until one of its children terminates.
父进程调用wait时,并没有对子进程做什么,它仅表示我关心子进程的状态变迁,并将自己切入到睡眠状态(暂停自己)。当子进程退出时,父进程被唤醒,通过wait返回值,父进程可以知道子进程退出原因。

23,209

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧