【问题标题】:What is related and unrelated processes?什么是相关流程和不相关流程?
【发布时间】:2020-08-18 05:34:22
【问题描述】:

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

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

fork()

但是,当我们调用 exec* 系列函数来替换程序映像时,我不确定该进程是否仍然被认为是相关的:

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

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

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

谢谢!

ref: mark mitchell: 高级 linux 编程

对管道的调用会创建文件描述符,这些描述符仅在该进程及其所在进程内有效 孩子们。进程的文件描述符不能传递给不相关的进程;然而, 当进程调用fork时,文件描述符被复制到新的子进程中。因此, 管道只能连接相关进程。

【问题讨论】:

  • all others are unrelated? 所有进程都是从 PID 1 创建的 => 所有进程都是“相关的”
  • 调用fork() 会创建一个与原始进程相同的子进程。调用exec() 不会改变两个进程之间的关系——子/父关系不受影响。但是,如果父级创建了管道并将它们标记为“执行时关闭”,那么调用exec() 的子级将导致管道关闭。

标签: c++ linux pipe ipc systems-programming


【解决方案1】:

我们可以说任何使用 fork() 创建的进程,无论是否 exec 或使用的原始程序映像总是相关的?

是的,我们可以。

无论您是否在子进程中调用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多