【问题标题】:how waitpid() function is implemented in system() function in linuxlinux中system()函数中waitpid()函数是如何实现的
【发布时间】:2013-08-21 19:02:30
【问题描述】:

我在阅读 Richard Stevens“UNIX 环境中的高级编程”时发现了这个主题。

*8.13。系统功能

*****因为system是通过调用fork、exec、waitpid来实现的,所以返回值有3种**

1.如果 fork 失败或 waitpid 返回 EINTR 以外的错误,则系统返回 –1 并设置 errno 以指示错误。

2。如果exec失败,表示shell无法执行,返回值就好像shell执行了exit(127)一样。

**3。否则,fork、exec 和 waitpid 这三个函数都会成功,并且 system 的返回值是 shell 的终止状态,格式为 waitpid 指定的格式。******

据我了解,我们 fork() 通过 cmdstring name 和 exec() 将其与父进程分开。

但无法弄清楚 waitpid() 函数 如何成为 system() 函数 调用的一部分?

下面的链接ambiguous constructor call while object creation没有给我正确的答案。

【问题讨论】:

    标签: c++ c linux


    【解决方案1】:

    在您关闭fork() 后,您的原始流程会立即继续,即fork() 立即返回。此时,新进程仍在运行。由于system() 应该是同步的,即必须只在执行的程序完成后返回,所以原程序现在需要在新进程的PID 上调用waitpid() 以等待其终止。

    在图片中:

       [main process]
             .
             .
             .
           fork()     [new process]
             A
            / \
           |   \
           |    \___  exec()
      waitpid()         .
          z             .
          z             . (running)
          z             .
          z           Done!
          z             |
          +----<----<---+
          |
          V
      (continue)
    

    【讨论】:

      【解决方案2】:

      system() 调用在 Unix 环境中看起来像这样:

      int system(const char *cmd)
      {
         int pid = fork();
         if(!pid)  // We are in the child process. 
         {
             // Ok, so it's more complicated than this, it makes a new string with a
             // shell in it, etc. 
             exec(cmd);
             exit(127);  // exec failed, return 127. [exec doesn't return unless it failed!]
         }
         else
         {
             if (pid < 0)
             {
                  return -1;   // Failed to fork!
             }
             int status;
             if (waitpid(pid, &status, 0) > 0)
             {
                 return status;
             }
         }
         return -1;
      }
      

      请注意,这是system 所做的象征性操作——它有点复杂,因为waitpid 可以给出其他值,以及需要检查的各种其他事情。

      【讨论】:

        【解决方案3】:

        来自手册页:

        system() 通过调用/bin/sh -c 命令执行command 中指定的命令,并在命令完成后返回。命令执行过程中,SIGCHLD 会被阻塞,SIGINT 和 SIGQUIT 会被忽略。

        system() 大概使用waitpid() 来等待shell 命令完成。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-10-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-21
          • 1970-01-01
          • 1970-01-01
          • 2012-01-18
          相关资源
          最近更新 更多