什么是相关和不相关的过程?

What is related and unrelated processes?

有人可以澄清相关和不相关流程的定义吗?

我知道 fork 创建了两个相关进程

fork()

但是我不确定我们调用exec*家族函数替换程序镜像时是否仍然认为进程是相关的:

if (child) {
   exec("path to binary", ...) <- Is it still related process
}

我问的原因是想弄清楚在什么场景下可以使用哪种IPC方式。例如,pipes 只允许在相关进程之间使用。所以我在上面要求澄清我编写的新程序(可能使用不同的语言)是否可以访问管道文件描述符。

我们是否可以说任何使用 fork() 创建的进程,无论使用的是 exec 还是原始程序映像,总是相关的,而其他所有进程都不相关?

谢谢!

ref: mark mitchell: 高级 linux 编程

A call to pipe creates file descriptors, which are valid only within that process and its children. A process’s file descriptors cannot be passed to unrelated processes; however, when the process calls fork, file descriptors are copied to the new child process.Thus, pipes can connect only related processes.

Can we say that any process created with fork() regardless of whether exec or original program image is used is always related?

是的,我们可以。

无论您是否在子进程中调用 exec,父进程和子进程仍然可以使用管道相互通信。请参阅下面创建子进程的示例,它将自身更改为 echo 然后父进程仍然可以读取其 echo 参数。

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <assert.h>

int main() {

  int filedes[2];
  int const pipeRes = ::pipe(filedes);
  assert(pipeRes != -1) ;

  pid_t pid = ::fork();
  assert(pid != -1);

  if (pid == 0) // child code                                                                                                                                                                                                               
    {
      // connect the entrance of the pipe to STDOUT_FILENO within the child process                                                                                                                                                         
      while ((::dup2(filedes[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
      // close both input and output of new pipe in child process                                                                                                                                                                           
      close(filedes[1]);
      close(filedes[0]);
      execl("/bin/echo", "echo", "child-says-hello", (char*)0);
      assert(false); // execl failed                                                                                                                                                                                                        
    }

  // parent code                                                                                                                                                                                                                            
  close(filedes[1]); // close input of new pipe in parent, it will only read from it                                                                                                                                                        

  char buffer[1024];
  while (1)
    {
      ssize_t count = read(filedes[0], buffer, sizeof(buffer));
      if (count == -1)
        {
          if (errno == EINTR) continue;
          else assert(false);
        }
      else if (count == 0)
        {
      // read everything                                                                                                                                                                                                                
          break;
        }
      else
        {
          std::cout << "received count:" << count << " bytes with: " << buffer << "\n";
        }
    }

  close(filedes[0]);
  wait(0);
  return 0;
}

输出为

eceived count:17 bytes with: child-says-hello

上面的代码示例基于 this tutorial