上海至河内机票:《UNIX环境高级编程》的笔记——wait&waitpid
来源:百度文库 编辑:偶看新闻 时间:2024/06/12 01:13:03
wait&waitpid 进程结束,无论是否正常中止,内核都会给它的父进程发送一个SIGCHILD的通知。(虽然这个老爸一点都不计划生育也不在乎孩子,但是孩子死了总得通知他一下吧)。显然这个通知是异步的,某天老爸下班回家可能就在邮箱里看到它若干孩子的死亡证明了。父进程是比较不负责任的,所以它可能随手把这个死亡证明扔了(ignore it),或者如果他比较爱那个孩子的话,就给它办个葬礼(signal handler)。呐,都说了这个老爸是不负责任的,所以default方式就是扔了。 作为一个进程,它调用wait或者waitpid的话会 1.block。 如果它所有的子进程都在运行(这里是否应该理解为这些子进程没有死掉) 2.带着某个子进程的中止状态立即返回。如果有一个子进程已经中止并等待它父进程来存取它的中止状态。 3,如果它已经没有子进程了,就以错误退出。 wait会使调用者block,直到它有某个子进程中止为止。而waitpid的第三个参数可使调用者不中止。 1、下面部分来自:http://haipo.me/blog/65
第八章进程控制,其中讲到了僵死进程,它的定义是这样的:
在 UNIX 术语中,一个已经终止,但其父进程尚未对其进行善后处理(获取终止进程的有关信息,释放它仍占 有 的资源)的进程被称为僵死进程( zombie )。
查看linux源代码 unistd.h 我们会发现,其实 wait 就是经过包装的 waitpid:staticinlinepid_twait(int*wait_stat){
returnwaitpid(-1,wait_stat,0);}
waitpid的返回值比wait稍微复杂一些,一共有3种情况:1. 当正常返回的时候,waitpid返回收集到的子进程的进程ID;2. 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;3. 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;当pid所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid就会出错返回,这时errno被设置为ECHILD;下面看一个简单的例子:下载:waitpid.c/* waitpid.c */#include#include#include#includeint main(){
pid_t pc,pr; pc=fork(); if (pc<0)/* fork错误*/ { printf("fork error\n"); exit(1); } else if(pc==0)/*在子进程中*/ { sleep(10); exit(0); } else { do {/* 使用了WNOHANG参数,waitpid不会在这里等待 */ pr=waitpid(pc,NULL,WNOHANG); if (pr==0) { printf("No child exit\n"); sleep(1); } }while (pr==0); if (pr==pc) printf("successfully get child %d\n",pr); else printf("wait child error\n"); } return 0;}
编译并运行:$ gcc -o waitpid waitpid.c$ ./waitpidNo child exitNo child exitNo child exitNo child exitNo child exitNo child exitNo child exitNo child exitNo child exitNo child exitsuccessfully get child 4607父进程经过10次失败的尝试之后,终于收集到了退出的子进程。父进程和子进程分别睡眠了10秒钟和1秒钟,代表它们分别作了10秒钟和1秒钟的工作。父子进程都有工作要做,父进程利用工作的简短间歇察看子进程的是否退出,如退出就收集它。
第八章进程控制,其中讲到了僵死进程,它的定义是这样的:
在 UNIX 术语中,一个已经终止,但其父进程尚未对其进行善后处理(获取终止进程的有关信息,释放它仍占 有 的资源)的进程被称为僵死进程( zombie )。
如果编写一个长期运行的程序,它调用 fork 产生了很多子进程,那么除非父进程等待取得子进程的终止状态,否则这些子进程终止后就会变成僵死进程。
我创建了一个子进程来做这些事情,和父进程并行运行,从而不引起服务中断。代码类似于:
...
if
((pid = fork()) == 0)
{
/* do some thing */
exit
(0);
}
...
这样子进程调用 exit() 进入终止状态后,父进程没有调用 wait() / waitpid() 函数,也没有显式忽略 SIGCHLD 信号,进程就会进入僵死状态。我在程序运行一段时间后,使用命令
ps
-ef |
grep
a.out
果然发现了很多僵死进程。僵死进程消耗很小的计算机资源,但是 Linux 系统对运行的进程数量有限制,如果产生过多的僵尸进程占用了可用的进程号,将会导致新的进程无法生成。但程序如果使用 wait() / waitpod() 阻塞等待的话,已经失去创建子进程的意义。
解决办法一:程序在进入终止状态时会向父进程发送 SIGCHLD 信号,在 linux 上,如果在程序开始运行时显式忽略该信号可以避免僵死进程的产生,代码如下:
if
(
signal
(SIGCHLD, SIG_IGN) == SIG_ERR)
{
fputs
(
"Cannot catch SIGCHLD\n"
, stderr);
exit
(1);
}
这样做并不是一个标准的做法,因为在某些 UNIX 操作系统上,忽略该信号并不能避免僵死进程的产生。
解决办法二:更好的做法是调用 signal() 函数接管 SIGCHLD 信号,父进程收到此信号后,执行 waitpid() 函数为子进程收尸。代码如下:
static
void
process_wait(
int
sig)
{
while
(waitpid(-1, NULL, WNOHANG) > 0)
;
}
...
if
(
signal
(SIGCHLD, process_wait) == SIG_ERR)
{
fputs
(
"Cannot catch SIGCHLD\n"
, stderr);
exit
(1);
}
...
waitpid() 函数在指定 WNOHANG 参数时,并不会阻塞进程运行。此时 waitpid() 作用为获得进程的运行信息,当子进程没有结束时返回值为 0, 在已经结束则返回值为子进程 ID. 2、下面的部分是转来的,源网址http://doc.linuxpk.com/53457.html查看linux源代码 unistd.h 我们会发现,其实 wait 就是经过包装的 waitpid:staticinlinepid_twait(int*wait_stat){
returnwaitpid(-1,wait_stat,0);}
waitpid的返回值比wait稍微复杂一些,一共有3种情况:1. 当正常返回的时候,waitpid返回收集到的子进程的进程ID;2. 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;3. 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;当pid所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid就会出错返回,这时errno被设置为ECHILD;下面看一个简单的例子:下载:waitpid.c/* waitpid.c */#include
pid_t pc,pr; pc=fork(); if (pc<0)/* fork错误*/ { printf("fork error\n"); exit(1); } else if(pc==0)/*在子进程中*/ { sleep(10); exit(0); } else { do {/* 使用了WNOHANG参数,waitpid不会在这里等待 */ pr=waitpid(pc,NULL,WNOHANG); if (pr==0) { printf("No child exit\n"); sleep(1); } }while (pr==0); if (pr==pc) printf("successfully get child %d\n",pr); else printf("wait child error\n"); } return 0;}
编译并运行:$ gcc -o waitpid waitpid.c$ ./waitpidNo child exitNo child exitNo child exitNo child exitNo child exitNo child exitNo child exitNo child exitNo child exitNo child exitsuccessfully get child 4607父进程经过10次失败的尝试之后,终于收集到了退出的子进程。父进程和子进程分别睡眠了10秒钟和1秒钟,代表它们分别作了10秒钟和1秒钟的工作。父子进程都有工作要做,父进程利用工作的简短间歇察看子进程的是否退出,如退出就收集它。
UNIX的编程通常有shell编程、高级语言编程(C/C++),从程序设计角度,请分别说明两种编程方式的不同。
UNIX的一道编程题
在linux+unix环境下可以编程吗
编程问题高级的
编程问题高级的编程问题高级的编程问题高级的编程问题高级的
Unix下C编程方面的资料
请问如何学习UNIX下的编程
请问如何学习UNIX下的编程
wince的编程环境?
编程问题高级的编程问题高级的
c++的高级编程是什么?
汇编语言的编程环境是什么
编程Unix 的 Python 有免费的吗?
UNIX脚本编程时能否编写有参数的函数?
《环境生态学》笔记
求ASP3.0高级编程的源代码
我的realplayer 不能放wai视频文件
脚本编程与高级程序语言编程本质上的区别
asp.net的运行环境和编程环境
JAVA 几个编程环境的比较?
编程的集成开发环境是什么意思
如何获得java的编程环境
编程在哪个环境里进行的
跪求《UNIX编程艺术》The Art of UNIX Programming(中文版) d的下载地址 是中文版哟!!