我让 2 个进程并行运行,它们与命名管道通信。我注意到一个奇怪的行为:每次写入都应该跟着读取,反之亦然!如果我们违反规则,程序会挂起,如果我们用 ctrl+C 终止它,孩子仍然会挂起,这意味着它不能再重新读取。
我的例子:
#!/bin/bash
shopt -u failglob
shopt -s extglob nullglob dotglob
function london (){
local message answer fifo id return exitcode
fifo=fifo_$RANDOM.$RANDOM.$RANDOM.$$
mkfifo ${fifo}
#trap 'rm -rf "$fifo"' EXIT
( berlin $fifo ) &
id=$!
echo "parent id: $$, child id: $id"
message='Greetings from London!(1)'
echo "$message" > $fifo
echo "1. parent sent it's 1st message"
#*****write-to-write error!*****#
message='Greetings from London!(2)'
#read -r answer < $fifo
echo "$message" > $fifo
echo "2. parent sent it's 2nd message"
wait
rm -rf $fifo
}
function berlin (){
local message answer fifo
fifo=$1
read -r answer < $fifo
echo 'Berlin says:> '"$answer"
#*****read-to-read error!*****#
#echo 'next' > $fifo
read -r answer < $fifo
echo 'Berlin says:> '"$answer"
}
london
在我插入“write-to-write”或“read-to-read”消息的点下,有两条注释行解决了这个问题,让我觉得上面的规则神秘地成立了!!!有什么想法吗?
这是输出:
parent id: 4921, child id: 4923
1. parent sent it's 1st message
2. parent sent it's 2nd message
Berlin says:> Greetings from London!(1)
谢谢!
我想现在一切都清楚了,并浓缩为一句话:“保持管道对读者开放”。
假设现在,我想为循环内的“一些”命令添加第二个输入文件描述符;我怎样才能做到这一点?这是我的新柏林功能:
function berlin (){
local message answer fifo
fifo=$1
while true; do
read -r answer
echo 'Berlin says:> '"$answer"
#this fails!
read -r -p "reading from fd0: " <&0
if [[ $answer = 'quit' ]]; then
break
fi
done < "$fifo" 3>"$fifo"
}
可以看到,我们使用文件描述符 3 作为管道,但是当我们尝试从 fd 0 读取时,我们实际上是从 fd 3 读取的!有没有办法做到这一点?