Bash中多进程队列的优秀实现是什么?
我正在考虑一个FIFO,每一行代表队列中的一个元素:
mkfifo fifo
ls > fifo
在另一个过程中:
read element < fifo
预期的结果是读者进程读取一行(即一个元素)并将其存储在变量$element
中,保持队列的其余部分不变,以便其他读取器进程可以获取元素(行)好。
不幸的是,这不起作用。 read
语句打开FIFO,导致编写器(ls
)立即完成,关闭FIFO然后似乎导致剩余数据被丢弃,其他元素无法被另一个进程读取(在事实上,下一个read < fifo
会挂起,直到另一个编写器出现并写入FIFO中。
我还考虑过触摸特殊目录中的文件(作为编写者)并移动文件(作为读者),但这似乎很乏味,显然对于数百万个队列条目是不可行的。
我能否以某种方式使FIFO变体工作?
是否有不同的实现shell队列的方法,有多个编写器和几个读取器,所有这些都在同一个队列上工作?
答案 0 :(得分:1)
你只需要保持PIPE开放
$mkfifo PIPE
$cat > PIPE &
管道现在无限期打开,直到你杀了猫。
$ls > PIPE &
$read Line < PIPE
$echo $Line
file1
您现在可以写下并阅读您的内心。
答案 1 :(得分:0)
我自己也找到了答案。我没有使用FIFO,而是使用简约的TCP服务器接受来自一个端口的输入并逐行写入输出。
要设置TCP服务器,我使用以下脚本:
nc -k -l 4444 | while read a
do echo "$a" | nc -l 4445
done
(当然,追加&
在后台运行此内容。)
然后作家可以这样做:
for ((i=0; i<10000; i++))
do
printf "x%02d\n" "$i"
done >/dev/tcp/127.0.0.1/4444
读者可以这样做:
while ! { read a < /dev/tcp/localhost/4445; } 2>/dev/null
do
sleep 2 # we poll; if there is nothing, we sleep between polls
done
echo "$a"
此脚本提取一个元素(行)并对其进行处理(echo "$a"
)。如果你想排空队列,请在循环中执行此操作。
我对投票解决方案并不是很满意,但是测试表明它可以与两位作者和两位读者一起可靠地工作(而且我不明白为什么更多的读者和作家应该提出问题)。