我是否必须为 C 中的每对进程创建一个新管道?
如果我有 4 个想要通过管道传输的进程:
process1 | process2 | process3 | process4
我是否必须像这样创建 3 个单独的管道
int pipe1[2];
int pipe2[2];
int pipe3[2];
,或者我可以以某种方式回收管道名称,如这个伪代码中所示:
int pipe1[2]; // we use ONLY two pipe names: pipe1
int pipe2[2]; // and pipe2
pipe(pipe1); // getting 2 file descriptors here
pipe(pipe2); // and 2 here
for process=1 to 4
if (process==3) // getting 2 new file descriptors for
pipe(pipe1); // process3|process4 (reusing pipe1)
fork() // forking here
if (child 1) then
use pipe1
if (child 2) then
use pipe1
use pipe2
if (child 3) then
use pipe2
use pipe1 //the pipe1 that we re-pipe()ed
if (child 3) then
use pipe1 //the pipe1 that we re-pipe()ed
这可行吗?我不确定重新管道1是否会对之前使用pipe1的分叉进程产生影响。
If I have 4 processes that I want to pipe:
process1 | process2 | process3 | process4
do I have to make 3 individual pipes likes this
int pipe1[2];
int pipe2[2];
int pipe3[2];
or can I somehow recycle pipe names like in this pseudocode:
int pipe1[2]; // we use ONLY two pipe names: pipe1
int pipe2[2]; // and pipe2
pipe(pipe1); // getting 2 file descriptors here
pipe(pipe2); // and 2 here
for process=1 to 4
if (process==3) // getting 2 new file descriptors for
pipe(pipe1); // process3|process4 (reusing pipe1)
fork() // forking here
if (child 1) then
use pipe1
if (child 2) then
use pipe1
use pipe2
if (child 3) then
use pipe2
use pipe1 //the pipe1 that we re-pipe()ed
if (child 3) then
use pipe1 //the pipe1 that we re-pipe()ed
Would this work? I am not sure if repiping pipe1 will have an impact on the previous forked processes that used pipe1.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
简短回答:
不,“重新管道”pipe1 不会对之前使用 pipeline1 的分叉进程产生影响,但最好在 fork()'ing 之前声明 3 个管道和 pipeline()'ing。
长答案:
为了理解原因,我们首先看看创建“管道”时会发生什么,然后看看“分叉”进程时会发生什么。
当你调用pipe()时,它
“创建一个管道(一个允许单向的对象
数据流)并分配一对文件描述符。第一个描述符连接到管道的读取端;第二个连接到写入端。”(来自 man 管道页面)
这些文件描述符存储到您传递给它的 int 数组中。
当您调用 fork() 时,“新进程(子进程)应是一个调用进程的精确副本”(这来自 man fork() 页面)
换句话说,父进程将创建一个子进程,并且该子进程将拥有它自己的数据副本所以
当孩子 3 打电话时pipeline(pipe1),它将创建一个新的管道,并将新的文件描述符存储在它自己的 pipeline1 变量的副本中,而不修改任何其他进程的 pipeline1
。声明两个管道变量并仅在子进程 3 中调用 pipeline() ,这不是很容易阅读,并且其他人(包括您自己)稍后在查看您的代码时会感到困惑
有关 fork() 和 的更多信息 。 pipeline() 的,请查看 http://beej.us /guide/bgipc/output/html/multipage/index.html
Short answer:
no, "repiping" pipe1 will not have an impact on the previous forked processes that used pipe1, but you're better off declaring 3 pipes and pipe()'ing before fork()'ing.
Long answer:
To understand why, let's first see what happens when you create a "pipe", and then what happens when you "fork" a process.
When you call pipe(), it
"creates a pipe (an object that allows unidirectional
data flow) and allocates a pair of file descriptors. The first descriptor connects to the read end of the pipe; the second connects to the write end." (This is from the man pipe page)
These file descriptors are stored into the int array you passed into it.
When you call fork(), "The new process (child process) shall be an exact copy of the calling process" (This is from the man fork() page)
In other words, the parent process will create a child process, and that child process will have it's own copy of the data.
So when child 3 calls pipe(pipe1), it will be creating a new pipe, and storing the new file descriptors in it's own copy of the pipe1 variable, without modifying any other process's pipe1.
Even though you can get away with only declaring two pipe variables and just calling pipe() in child 3, it's not very easy to read, and other's (including yourself) will be confused later on when they have to look at your code.
For more on fork()'s and pipe()'s, take a look at http://beej.us/guide/bgipc/output/html/multipage/index.html
我过去这样做的方式,以及我再次这样做的方式,就是不重复使用管道,最终得到 N-1 根管道。它还取决于您是否希望同时运行两个以上的进程进行通信,如果是这样,那么您显然会在重用 2 个管道时遇到问题。
The way I've done it in the past, and the way I would do it again, was to not reuse pipes and end up with N-1 pipes. It would also depend on whether or not you want to have more than two process running at the same time communicating, if so then you'd obviously have problems with reusing 2 pipes.
对于命令中的每个
|
字符,您需要一个管道,因此需要调用一次pipe()
。不过,您不需要使用三个单独的
int [2]
数组来存储管道文件描述符。系统并不关心您将管道文件描述符存储在哪个变量中 - 它们只是 int 。You need one pipe, and thus one call to
pipe()
, for each|
character in your command.You do not need to use three separate
int [2]
arrays to store the pipe file descriptors, though. The system does not care what variable you store the pipe file descriptors in - they are justint
s.