Patryk,您为什么要使用fifo,而且在管道的每个阶段都使用相同的fifo?
在我看来,每个阶段之间都需要一个管道。因此流程如下所示:
Shell ls tr tr----- ---- ---- ----pipe(fds);fork(); close(fds[0]); close(fds[1]); dup2(fds[0],0); pipe(fds); fork(); close(fds[0]); close(fds[1]); dup2(fds[1],1); dup2(fds[0],0); exex(...); pipe(fds); fork(); close(fds[0]); etc dup2(fds[1],1); exex(...);
在每个分叉的外壳程序(close,dup2,pipe等)中运行的序列看起来像一个函数(带有所需进程的名称和参数)。请注意,直到
exec每个调用之前,shell的分支副本都在运行。
编辑:
帕特里克:
Also, is my thinking correct? Shall it work like that? (pseudopre): start_fork(ls) -> end_fork(ls) -> start_fork(tr) -> end_fork(tr) -> start_fork(tr) -> end_fork(tr)
我不确定start_fork和end_fork是什么意思。您是否暗示开始
ls之前要完成
tr?这并不是上面的图真正的意思。您的外壳程序将
ls在启动之前不等待完成
tr。它开始的所有过程的按顺序配管,设置
stdin和
stdout为每一个,以使工艺连接在一起,
stdout的
ls到
stdin的
tr;
stdout的
tr到
stdin了下
tr。这就是dup2调用正在执行的操作。
进程的运行顺序由操作系统(调度程序)确定,但很显然,如果进程正在
tr运行并从空读取,
stdin则必须等待(阻塞),直到前一个进程向管道中写入内容为止。甚至有
ls可能
tr从它的读取之前就完成了
stdin,但是也有可能不会完成。例如,如果链中的第一个命令是连续运行的并且一直沿途产生输出,那么无论第一个命令沿管道发送什么,管道中的第二个命令都会不定期地进行处理。
希望能使事情澄清一些:-)



