【问题标题】:why the command 'exec' can remove the blocking state of fifo file?为什么命令'exec'可以消除fifo文件的阻塞状态?
【发布时间】:2021-12-31 12:55:39
【问题描述】:

我正在研究如何使用多线程来处理任务。我注意到fifo文件可以帮助解决这个问题。效果如下:

#!/bin/bash
my_cmd(){
echo "process $1"
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个cmd,一次10个)。我稍微修改了这个脚本

#!/bin/bash
my_cmd(){
echo "process $1"
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"

果然,第二个脚本也可以正常运行了。但是我再次修改时出错了。

#!/bin/bash
my_cmd(){
echo "process $1"
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文件进入了阻塞状态。似乎这个命令'exec 7$ff'解除了这个fifo文件的阻塞状态。那么是这样吗?

【问题讨论】:

    标签: multithreading shell exec mkfifo


    【解决方案1】:

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

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

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

    为了与自己通信而使用连接两端的进程应该非常小心以避免死锁。

    【讨论】:

    • 所以这个命令只在读写端打开fifo文件?
    • @dotzhang 作为文件描述符 7,所以它可以像第一个一样在以后使用,是的。
    猜你喜欢
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 2016-12-29
    • 1970-01-01
    • 2011-09-23
    相关资源
    最近更新 更多