我可以通过管道将任何两个进程相互连接吗?

qdi*_*dii 8 linux process bsd pipe fork

这个页面,从设计和4.4BSD操作系统的实现,据说:

管道和套接字的主要区别在于管道需要一个共同的父进程来建立通信通道

但是,如果我记录正确,则创建新流程的唯一方法是创建fork现有流程。所以我真的看不出两个进程怎么可能没有共同的祖先。那么我认为任何一对进程都可以通过管道相互连接是否正确?

Mat*_*Mat 7

那么我认为任何一对进程都可以通过管道相互连接是否正确?

并不真地。

管道需要在子进程分叉之前由父进程设置。一旦子进程被分叉,它的文件描述符就不能被“从外部”操作(忽略调试器之类的东西),父进程(或任何其他进程)不能在事后做“设置通信通道”部分.

所以如果你拿两个已经在运行的随机进程,你不能直接在它们之间设置管道。您需要使用某种形式的套接字(或其他 IPC 机制)来让它们进行通信。(但请注意,某些操作系统,其中包括 FreeBSD,允许您在 Unix 域套接字上发送文件描述符。)


Gil*_*il' 6

这句话不是很清楚。首先,parent应该是祖先,因为设置管道的进程可以是父进程,或祖父母,或曾祖父-\xe2\x80\xa6-祖父母,或通信进程之一。其次,这句话的意思并不是\xe2\x80\x9cif you Want a Pipe, there must exit a common successor process\xe2\x80\x9d,而是\xe2\x80\x9cif you Want a Pipe, a common successor process必须设置\xe2\x80\x9d。

\n\n

在底层,一个进程与自身建立了一个管道。管道是一个像其他文件描述符一样的文件描述符,或者更准确地说是一对文件描述符,每一端一个。创建管道的进程可以立即使用它向自身发送数据,尽管这很少有用(尽管自管道确实有其用处)。

\n\n

一种典型的习惯用法是进程建立一个管道,然后分叉一个子进程,并在父进程中关闭管道的一端,在子进程中关闭管道的另一端。这使得父进程和子进程可以在一个方向上进行通信。如果进程需要双向通信,则它们需要两个管道(除了某些 UNIX 变体,管道是双向的)。

\n\n

管道由任何子进程依次继承,因此创建管道的进程可能不参与通信。例如,在两个外部命令之间创建的 shell 中的管道ls | rot13涉及以下步骤:

\n\n
    \n
  • 外壳创建一个管道。
  • \n
  • shell fork 一个进程。子进程关闭管道的读取端并execve调用ls
  • \n
  • shell fork 一个进程。子进程关闭管道的写入端并execve调用rot13
  • \n
  • shell 关闭管道的两端并等待两个子进程退出。
  • \n
\n\n

如果两个现有进程想要相互通信,它们可以使用命名管道。(嗯,还有文件描述符传递,但它不适合胆小的人。)

\n