免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4192 | 回复: 8
打印 上一主题 下一主题

请教fork()和wait()的几个问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-11-23 17:45 |只看该作者 |倒序浏览
各位同仁您好:
     因初学乍用此函数, 请教几个问题,请不吝指点:
     程序代码段1-------
      if (i<=5)
       {
         if ( fork() == 0 )
           {
               / * 子进程执行此命令 */
               execlp( command, command );
              / * 如果exec函数返回,表明没有正常执行命令,打印错误信息*/
               exit( errorno );
           }
           else
           {
              /* 父进程 */
              i++;
           }
       }
        else
       {
            wait ( &rtn );
            i--;
       }
         
        我循环用execlp()函数起5个子进程,ps -ef|grep 看到比如pro1,pro2,pro3,pro4,pro5
如果我在执行“程序代码段1”时,pro1,pro2子进程结束了,那父程序再执行到wait ( &rtn );
时会不会接收到pro1和pro2结束的信息,此时一个wait()能同时接收到pro1,pro2结束id?
     wait()函数需要和execl()起的程序一一对应吗?也就是说有多少个fork(){execl(0)},就必须有多少个
wait()函数吗?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2005-11-23 18:18 |只看该作者
我想你应该处理一下 SIGCHLD信号.即使用最简单的signal函数处理也好.
比如
在主函数中 if(signal(SIGCHLD,fn)!=SIG_ERR)..........

fn函数.
void fn(int sign)
{
....在这里调用wait或者waitpid函数来处理.
}

具体详见 <<Unix高级环境编程>>信号那章.或者其他书里对信号都有讲解.

论坛徽章:
0
3 [报告]
发表于 2005-11-29 22:59 |只看该作者
赞成楼上的,否则子进程就僵掉了,WAIT也没有用

论坛徽章:
0
4 [报告]
发表于 2005-11-29 23:52 |只看该作者
没必要使用 SIGCHLD。wait 会阻塞直到某个子进程退出为止;如果已经有子进程结束运行成为僵尸进程,wait 会直接清理这个子进程的资源并返回退出状态(exit code)。

  1.      1  #include <unistd.h>
  2.      2  #include <sys/types.h>
  3.      3  #include <sys/wait.h>
  4.      4  #include <stdio.h>
  5.      5  #include <stdlib.h>
  6.      6
  7.      7  int main()
  8.      8  {
  9.      9      int i = 0;
  10.     10
  11.     11      for (i = 0; i < 5; ++i) {
  12.     12          if (fork()) {
  13.     13              continue;
  14.     14          } else {
  15.     15              printf("Child %d: exit( %d )\n", (int) getpid(), i);
  16.     16              exit(i);
  17.     17              // exit, make zombie
  18.     18          }
  19.     19      }
  20.     20
  21.     21      sleep(2);                   // Wait for all child to exit
  22.     22      for (i = 0; i < 6; ++i) {
  23.     23          int stat;
  24.     24          int rt;
  25.     25          rt = wait(&stat);
  26.     26          if (rt > 0)
  27.     27              printf("Child %d exit status: %d\n", rt, WEXITSTATUS(stat));
  28.     28          else if (rt < 0)
  29.     29              perror("wait()");
  30.     30          fflush(NULL);
  31.     31      }
  32.     32  }
复制代码


创建了五个进程,两秒钟在正常情况下应已经全部退出。随后主进程调用 wait 6次。运行时注意一下最后一次的输出。:)

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
5 [报告]
发表于 2005-11-30 08:07 |只看该作者
原帖由 wolf0403 于 2005-11-29 23:52 发表
没必要使用 SIGCHLD。wait 会阻塞直到某个子进程退出为止;如果已经有子进程结束运行成为僵尸进程,wait 会直接清理这个子进程的资源并返回退出状态(exit code)。

[code]     1  #include <unistd.h>
...


wait调用阻塞父进程了. 我遇到的需求一般都是父进程还要干其他的事. 需要异步信号来通知处理的.
通用的方法还是采取处理SIGCHLD信号.

论坛徽章:
0
6 [报告]
发表于 2005-11-30 08:35 |只看该作者
不错,如果主进程不适合阻塞等待,可以用 SIGCHLD ,也可以通过 wait3 / wait4 + WNOHANG 论询。
不过看楼主的意思和代码,似乎这里等待是合理的。

论坛徽章:
0
7 [报告]
发表于 2005-11-30 17:56 |只看该作者
我曾经用waitpid(id,NULL,0)函数等待PID为id的子进程退出信息,但跟踪到子进程的_exit(0)之前,表明子进程已经退出,但是waitpid函数没有返回,不知道这是什么原因。另外,这种现象不是经常发生。

论坛徽章:
0
8 [报告]
发表于 2005-11-30 21:08 |只看该作者
to hskun: 这个情况是在运行期间就出现,还是只在 gdb 追踪的时候才会出现?

论坛徽章:
0
9 [报告]
发表于 2006-07-28 21:40 |只看该作者
wait系统调用会使父进程阻塞直到一个子进程结束或者是父进程接受到了一个信号.如果没有父进程没有子进程或者他的子进程已经结束了wait回立即返回.成功时(因一个子进程结束)wait将返回子进程的ID,否则返回-1,并设置全局变量errno.stat_loc是子进程的退出状态.子进程调用exit,_exit 或者是return来设置这个值. 为了得到这个值Linux定义了几个宏来测试这个返回值.
WIFEXITED:判断子进程退出值是非0
WEXITSTATUS:判断子进程的退出值(当子进程退出时非0).
WIFSIGNALED:子进程由于有没有获得的信号而退出.
WTERMSIG:子进程没有获得的信号号(在WIFSIGNALED为真时才有意义).

两位讨论的核心就是在这里了,不过一般都是要等待一个信号.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP