没有FIFO的进程间通信

dav*_*ide 10 bash file-descriptor fifo

在BASH脚本中,我们可以在后台运行多个进程,这些进程使用命名管道进行互通,在文件系统上注册FIFO.这方面的一个例子可能是:

#!/bin/bash
mkfifo FIFO

# BG process 1
while :; do echo x; done & >FIFO

# BG process 2
while :; do read; done & <FIFO

exit
Run Code Online (Sandbox Code Playgroud)

我想知道是否可以在不使用文件系统上的FIFO的情况下在脚本的后台进程之间进行相同的相互通信,也许可以使用某种文件描述符重定向.

小智 16

这是一个运行两个子进程的示例,它们实现为相同shell脚本的函数...一个子进程生成数字1 ... 5(在打印之间休眠),第二个从固定文件描述符读取(5,STDOUT为第一个FD被重定向到),乘以2并再次打印.主进程将第二个进程的STDOUT重定向到另一个固定的文件描述符(6),然后在循环中从那个进程读取.

它的工作方式与使用pipe(2)系统调用创建的fd对的C代码基本相同.要理解发生了什么,请在strace -f下运行脚本!

Bash Version是在Ubuntu/x86上运行的4.2.24(1).

[ubuntu /home/chris]
$ bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Run Code Online (Sandbox Code Playgroud)

脚本输出:

[ubuntu /home/chris]
$ ./read_from_fd.sh
Got number 2.
Got number 4.
Got number 6.
Got number 8.
Got number 10.
Run Code Online (Sandbox Code Playgroud)

源代码:

#!/bin/bash

# Generate data, output to STDOUT.
generate_five_numbers() {
        for n in `seq 5` ; do
                echo $n
                sleep 2
        done
}

# Read data from FD#5, multiply by two, output to STDOUT.
multiply_number_from_fd5_by_two() {
        while read n <&5 ; do
                echo "$(( $n * 2 ))"
        done
}

# choose your FD number wisely ;-)

# run generator with its output dup'ed to FD #5
exec 5< <( generate_five_numbers )

# run multiplyier (reading from fd 5) with output dup'ed to FD #6
exec 6< <( multiply_number_from_fd5_by_two )

# read numbers from fd 6
while read n <&6 ; do
        echo "Got number $n."
done
Run Code Online (Sandbox Code Playgroud)

运行时处理树:

??read_from_fd.sh(8118)???read_from_fd.sh(8119)???sleep(8123)
                        ??read_from_fd.sh(8120)
Run Code Online (Sandbox Code Playgroud)


Pau*_*ce. 5

重击4具有协同处理

您还可以使用匿名命名管道,也就是Bash 2、3或4中的进程替换