在bash中使用管道来缓冲来自串行设备的数据

时间:2013-07-22 21:02:28

标签: bash serial-port

我的脚本看起来像:

while true; do
    read -t10 -d$'\n' input_from_serial_device </dev/ttyS0
    # do some costly processing on the string
done

问题是它将错过串行设备的下一个输入,因为它正在燃烧CPU周期进行昂贵的字符串处理。

我认为我可以通过使用管道解决这个问题,原因是bash会缓冲两个进程之间的输入:

( while true; do
     read -d$'\n' input_from_serial_device </dev/ttyS0
     echo $input_from_serial_device
  done ) | ( while true; do
     read -t10 input_from_first_process
     # costly string processing
  done )

我首先要检查我是否正确理解了管道,这确实会像我预期的那样缓冲两个进程之间的输入。这个想法是否正确?

其次,如果我在第二个进程中找到了我正在寻找的输入,是否有办法立即终止两个进程,而不是从第二个进程退出并在退出第一个进程之前等待下一个输入?

最后,我意识到bash不是最好的方法,而且我目前正在开发一个C程序,但我非常希望将其作为一个中间解决方案。

谢谢!

1 个答案:

答案 0 :(得分:6)

问题不在于管道。这是串口设备。

写作时

while true; do
  read -t10 -d$'\n' input_from_serial_device </dev/ttyS0
  # use a lot of time
done

结果是打开了串行设备,从中读取了一行,然后关闭了它。然后在# use a lot of time完成之前不再打开它。当串行设备未打开时,输入的串行输入将被丢弃。

如果输入真的比它可以处理的更快,那么缓冲是不够的。你必须扔掉输入。另一方面,如果它以允许处理的平均速度运球,那么您应该能够通过保持串行设备打开来实现您想要的效果:

while true; do
  read -t10 -r input_from_serial_device
  # process input_from_serial_device
done < /dev/ttyS0

注意:我在-r来电时添加了read - 几乎肯定是必要的 - 并删除了-d$'\n',因为这是默认设置。