bash – 关于FIFO和文件描述符的问题
我写了一个这样的脚本:
N=5 FIFO=/tmp/$$.fifo mkfifo $FIFO loop(){ for i in $(seq 1 $N); do read tmp < $FIFO echo "$i out" done } loop & LOOP_PID=$! for i in $(seq 1 $N); do echo $i > $FIFO echo "$i in" done wait $LOOP_PID 当我运行脚本时,它停止等待$LOOP_PID并且无法继续. 所以我用文件描述符修改脚本: N=5 FIFO=/tmp/$$.fifo mkfifo $FIFO exec 3<>$FIFO loop(){ for i in $(seq 1 $N); do read -u3 tmp echo "$i out" done } loop & LOOP_PID=$! for i in $(seq 1 $N); do echo $i >&3 echo "$i in" done wait $LOOP_PID 还可以. 当我直接使用FIFO时,它无法连续从FIFO中读取数据,它会挂起.当我使用文件描述符时,它没关系.是什么原因? 解决方法
替换这个:
loop(){ for i in $(seq 1 $N); do read tmp < $FIFO echo "$i out" done } 有了这个: loop(){ for i in $(seq 1 $N); do read tmp echo "$i out" done < $FIFO } 这使得fifo保持打开状态,而不是每次循环重新打开并重新关闭它. FIFO非常棘手: >除非另一个进程准备好从FIFO读取,否则尝试写入FIFO将被阻止. 这意味着上述脚本的行为方式可能取决于计时事故.当读取tmp< $FIFO正在执行,有多少行写入FIFO? read将只读取第一个,当FIFO关闭时,其余的将被丢弃. exec语句如何帮助 我们来比较两个脚本.第一个直接使用FIFO: #!/bin/sh fifo=/tmp/$$.myfifo mkfifo "$fifo" echo $'1n2n3n4'>"$fifo" for i in {1..4} do read tmp echo $tmp done <"$fifo" 在等待进程开始读取FIFO时,上述脚本将在第一个回显期间挂起.因为它挂起,所以永远不会到达读取tmp语句,并且此脚本不会产生任何输出. 第二个使用exec来创建文件句柄: #!/bin/sh fifo=/tmp/$$.myfifo mkfifo "$fifo" exec 3<>"$fifo" echo $'1n2n3n4'>&3 for i in {1..4} do read -u3 tmp echo $tmp done 此脚本不会挂起并将生成四行输出.不同之处在于shell为文件句柄提供缓冲.因此,当第一个echo语句尝试写入FIFO时,shell已准备好从FIFO读取. shell读取的数据可用于读取-u3 tmp语句. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |