【发布时间】:2020-05-11 20:23:02
【问题描述】:
我有一个行缓冲数据流,以及来自其他进程的许多读取器
读取器需要动态附加到系统,写入流的进程不知道它们
首先我尝试阅读每一行并将它们简单地发送到很多管道
#writer
command | while read -r line; do
printf '%s\n' "$line" | tee listeners/*
done
#reader
mkfifo listeners/1
cat listeners/1
但这会消耗大量 CPU
所以我想写一个文件并反复清理它
#writer
command >> file &
while true; do
: > file
sleep 1
done
#reader
tail -f -n0 file
但有时,一行在截断之前没有被一个或多个读取器读取,从而产生竞争条件
有没有更好的方法来实现这一点?
【问题讨论】:
-
command | tee listeners/*你为什么要绕行?that's consume a lot of CPU哇,为什么?你是怎么测量的?通常的方法是在 posix 兼容的系统上创建管道,在 bash 上通常的方法是使用command | tee >(listener1) >(listener2) | listener3 -
可以创建新的监听器,但不会更新通配符扩展
-
需要缓冲行吗? IE。如果有新的听众出现,他是否需要读取所有数据?您应该使用
while IFS= read -r line,否则它将删除前导和尾随空格。可能会很慢 - 对于每一行,您正在运行 3 个进程readprintf和tee。 -
您用“shell”标记了这个问题,这意味着您想要仅 posix 的解决方案?如果您使用
bash进行标记,您的问题将会接触到更多人。 -
鉴于对性能的关注(由 CPU 利用率和缺少的行暗示) - 如果您提供输入(频率、大小、消息/秒)和消费者(这些脚本是? 程式 ?)。看起来一个简单的解决方案行不通 - 其他详细信息将有助于提出解决方案