请教fork()和wait()的几个问题

发布于 2022-09-30 08:15:05 字数 1772 浏览 18 评论 0

各位同仁您好:
     因初学乍用此函数, 请教几个问题,请不吝指点:
     程序代码段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()函数吗?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

黑寡妇 2022-10-07 08:15:05

我想你应该处理一下 SIGCHLD信号.即使用最简单的signal函数处理也好.
比如
在主函数中 if(signal(SIGCHLD,fn)!=SIG_ERR)..........

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

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

花期渐远 2022-10-07 08:15:05

赞成楼上的,否则子进程就僵掉了,WAIT也没有用

尘曦 2022-10-07 08:15:05

没必要使用 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次。运行时注意一下最后一次的输出。:)

維他命╮ 2022-10-07 08:15:05

原帖由 wolf0403 于 2005-11-29 23:52 发表
没必要使用 SIGCHLD。wait 会阻塞直到某个子进程退出为止;如果已经有子进程结束运行成为僵尸进程,wait 会直接清理这个子进程的资源并返回退出状态(exit code)。

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

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

め七分饶幸 2022-10-07 08:15:05

不错,如果主进程不适合阻塞等待,可以用 SIGCHLD ,也可以通过 wait3 / wait4 + WNOHANG 论询。
不过看楼主的意思和代码,似乎这里等待是合理的。

花之痕靓丽 2022-10-07 08:15:05

我曾经用waitpid(id,NULL,0)函数等待PID为id的子进程退出信息,但跟踪到子进程的_exit(0)之前,表明子进程已经退出,但是waitpid函数没有返回,不知道这是什么原因。另外,这种现象不是经常发生。

感性不性感 2022-10-07 08:15:05

to hskun: 这个情况是在运行期间就出现,还是只在 gdb 追踪的时候才会出现?

时光匆匆的小流年 2022-10-07 08:15:05

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

两位讨论的核心就是在这里了,不过一般都是要等待一个信号.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文