BLUESKY
一步一个脚印向前走

今天看了unix网络编程中的关于wait和waitpid的区别,它采用的验证例子是客户/服务器的连接问题
 
1.当子进程结束的时候,父进程会收到SIGCHLD通知
  2.进程可以调用wait/waitpid等待此Signal
    a.当所有子进程都在执行的时候,会block
    b.当某个子进程中止,成为zombie的时候,立刻返回
    c.如果没有任何子进程,则返回错误

以前曾经学过这两函数的使用,但是没有什么例子可以验证,今天巧遇网络编程,就把这两个函数重新温习一下:
pid_t wait(int *stat_loc);
pid_t waitpid(pid_t pid, int *stat_loc, int options);



上面就是两个函数的声明
stat_loc返回的是子进程的终止状态,是个整型值,可以通过一些宏定义来检测终止的状态,暂时不介绍了
The pid argument specifies a set of child processes for which status is requested.
The waitpid() function shall only return the status of a child process from this set:
  If pid is equal to (pid_t)-1, status is requested for any child process. In this respect, waitpid() is then equivalent to wait().
  If pid is greater than 0, it specifies the process ID of a single child process for which status is requested.
  If pid is 0, status is requested for any child process whose process group ID is equal to that of the calling process.
  If pid is less than (pid_t)-1, status is requested for any child process whose process group ID is equal to the absolute value of pid.

The options argument is constructed from the bitwise-inclusive OR of zero or more of the following flags, defined in the <sys/wait.h> header:
    [WCONTINUED]
    The waitpid() function shall report the status of any continued child process specified by pid whose status has not been reported
    since it continued from a job control stop.
    [WNOHANG]
    The waitpid() function shall not suspend execution of the calling thread if status is not immediately available for one of the child processes specified by pid
    [WUNTRACED]
    The status of any child processes specified by pid that are stopped, and whose status has not yet been reported since they stopped,
    shall also be reported to the requesting process

    下面我们来具体看看wait和waitpid在网络编程中使用的区别:

void sig_chld(int signo)
{
  pid_t pid;
  
int stat;
  pid 
= wait(&stat);
  printf(
"child %d terminated \n",pid);
  
return;
}

void sig_chld(int signo)
{
  pid_t pid;
  
int stat;
  
while((pid = waitpid(-1,&stat,WNOHANG))>0)
  printf(
"child %d terminated \n",pid);
  
return;
}


  上面是两段不同的信号处理函数,它们的结果可能相差很多的,下面我们就来看看有哪些区别:
  首先我们看看用wait函数产生的效果:
  1、下面的输出是在启动客户端和服务器端程序后的ps输出
  备注:在客户端程序中,我们连续产生5个服务器连接进程,所以一共6个waitsrv进程



  2、下面是在客户端输入ctrl+d后的服务器端输出和ps查询后的结果





  我们从上面可以看出利用wait的一个致命的缺点就是只能回收一个子进程,其他的进程由于没有得到回收而变成僵尸进程

  下面我们来看看利用waitpid函数的输出结果:
   1、启动服务器端和客户端后的ps输出



  2、在客户端输入ctrl+d后的服务器端输出和ps的结果





   我们可以发现所有服务器的子进程在接受到客户端输入的EOF后,都被回收了!
 
   由此,我们可以发现,为了减少僵尸进程的产生,我们可以采用waitpid而减少wait的使用,虽然僵尸进程可以由init回收
   以上的例子程序是采用的unix网络编程中的例子,在此代码就不再详细列出了!
posted on 2007-09-04 09:21 LG 阅读(2013) 评论(0)  编辑 收藏 引用 所属分类: UnixProgram

<2007年9月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

常用链接

相册

最新评论