为什么命令'exec'可以解除fifo文件的阻塞状态?

why the command 'exec' can remove the blocking state of fifo file?

我正在研究如何使用多线程处理tasks.And我注意到fifo文件可以帮助that.here是效果:

#!/bin/bash
my_cmd(){
echo "process "
sleep 3
}
ff="d:/myfifo/$$.fifo"
mkfifo $ff
exec 7<>$ff
for i in {1..10};do echo;done >&7
for i in {1..1000};do {
read -u 7
my_cmd $i
echo >&7
}& done
rm $ff
wait
echo "end"

这个 shell 脚本可以 运行 正常(处理 1000 个命令,一次 10 个)。我稍微修改了这个脚本

#!/bin/bash
my_cmd(){
echo "process "
sleep 3
}
ff="d:/myfifo/$$.fifo"
mkfifo $ff
exec 7<>$ff
for i in {1..10};do echo;done >$ff     # modified
for i in {1..1000};do {
read <$ff                              # modified
my_cmd $i
echo >$ff                              # modified
}& done
wait
rm $ff
echo "end"

果然第二个脚本也可以运行 normally.But我再修改的时候出错了

#!/bin/bash
my_cmd(){
echo "process "
sleep 3
}
ff="d:/myfifo/$$.fifo"
mkfifo $ff
# exec 7<>$ff                                 modified
for i in {1..10};do echo;done >$ff    
for i in {1..1000};do {
read <$ff                              
my_cmd $i
echo >$ff                              
}& done
wait
rm $ff
echo "end"

脚本等待fifo文件的输入,因为fifo文件进入了阻塞state.It似乎这个命令'exec 7<>$ff'解除了这个fifo的阻塞状态file.So是这个案例?

在Linux上,至少(不确定其他操作系统,并且POSIX没有定义行为),打开一个fifo用于读取和写入将立即成功而不会阻塞等待为管道的另一端打开。

所以当你注释掉exec 7<>$ff行时,下一行for i in {1..10};do echo;done >$ff将打开fifo进行写入,并在继续之前阻止等待其他东西打开它进行写入。原版使用exec,已经开放阅读,无需屏蔽。

Linux fifo(7) documentation确实注意到了

A process that uses both ends of the connection in order to communicate with itself should be very careful to avoid deadlocks.