2

我正在阅读 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——都成功,并且系统的返回值是 shell 的终止状态,格式为 waitpid 指定的。******

据我了解,我们通过cmdstring 名称fork()一个进程,而exec()使其与父进程分开。

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

下面的链接模棱两可的构造函数调用,而对象创建没有为我提供正确的答案。

4

3 回答 3

15

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

在一张图片中:

   [main process]
         .
         .
         .
       fork()     [new process]
         A
        / \
       |   \
       |    \___  exec()
  waitpid()         .
      z             .
      z             . (running)
      z             .
      z           Done!
      z             |
      +----<----<---+
      |
      V
  (continue)
于 2013-08-21T19:05:49.133 回答
2

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

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可以给出其他值,以及需要检查的各种其他事情。

于 2013-08-21T19:12:11.147 回答
1

从手册页:

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

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

于 2013-08-21T19:06:39.667 回答