Bash中的多进程队列



Bash中多进程队列的良好实现是什么?

我正在考虑一个FIFO,每一行代表队列中的一个元素:

mkfifo fifo
ls > fifo

在另一个过程中:

read element < fifo

预期的结果是,读取器进程读取一行(即一个元素)并将其存储在变量$element中,使队列的其余部分保持不变,以便其他读取器进程也可以获得元素(行)。

不幸的是,这不起作用。read语句打开FIFO,导致写入程序(ls)立即完成,然后关闭FIFO似乎会导致剩余数据被丢弃,其他元素无法由另一个进程读取(事实上,下一个read < fifo挂起,直到另一个写入程序出现并写入FIFO)。

我还考虑过触摸特殊目录中的文件(作为编写器),并将文件移走(作为读取器),但这似乎很乏味,对于数百万队列条目来说显然是不可行的。

我能让FIFO变体以某种方式工作吗?

有没有不同的方法来实现shell队列,让几个编写器和几个读取器都在同一个队列上工作?

我自己可能已经找到了答案。我使用的不是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%02dn" "$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")。如果您想排出队列,请循环执行此操作。

我对民意调查解决方案不太满意,但测试表明,它在两个作者和两个读者的情况下可靠地工作(我不明白为什么更多的读者和作者会带来问题)。

您只需要保持PIPE打开

$mkfifo PIPE
$cat > PIPE &

管道现在无限期地打开,直到你杀死猫。

$ls > PIPE &
$read Line < PIPE
$echo $Line
 file1

你现在可以随心所欲地写作和阅读了。

最新更新