jam*_*fer 5 command-line scripts dd
我使用此命令从命名管道读取连续数据:
{ while :; do dd iflag=fullblock iflag=nonblock bs=65536 count=1 2> /dev/null | redis-cli -x PUBLISH myChannel ; done } < myFifo
Run Code Online (Sandbox Code Playgroud)
问题是,即使我同时运行 50 个命令,CPU 使用率也会很高。该过程应该是长时间运行的,并且其中许多过程应该同时工作。
那么,其原因是什么以及如何预防呢?谢谢。
如果我没记错的话,您正在使用dd缓冲目的...在您的情况下可能不需要循环...dd如果您不设置,将继续读取并提供指定大小的数据块count(这指示dd在完成指定的读/写次数后退出)或iflag=nonblock(You\xe2\x80\x99d 希望阻塞 I/O成功启动读取并继续从命名管道读取dd)并像这样使用它:
dd if=myFifo iflag=fullblock bs=65536 2> /dev/null | redis-cli -x PUBLISH myChannel\nRun Code Online (Sandbox Code Playgroud)\n在这种情况下,它应该仅在到达输入文件末尾时退出(例如,当命名管道的编写器终止/关闭管道时)。
\n或者要保持管道始终打开等待写入,请像这样使用它:
\ntail -c +1 -F myFifo | dd iflag=fullblock bs=65536 2> /dev/null | redis-cli -x PUBLISH myChannel\nRun Code Online (Sandbox Code Playgroud)\n或者,如果您的应用程序期望流/管道结束(例如EOF或close_write...顺便说一句,这不是流应用程序的最佳选择),请使用GNU 并行,如下所示:
tail -c +1 -F myFifo | parallel --max-procs 1 -P 1 -j 1 --pipe --block 64k -k \'redis-cli -x PUBLISH myChannel\'\nRun Code Online (Sandbox Code Playgroud)\n这应该类似于您的循环,但仅在您需要它的地方 \xe2\x80\xa6 它将以一种相当受控和资源感知的方式执行 \xe2\x80\xa6 它也应该保持命名管道即使在写入之间也保持打开状态,保留每一位流并缩短管道。
\n它while :正在向您的 CPU 发送垃圾邮件。任何循环中的命令while :;都会导致 CPU 使用率过高。例如:
while :; do echo foo > /dev/null; done
Run Code Online (Sandbox Code Playgroud)
或者,更明显的是,无操作:
while :; do true; done
Run Code Online (Sandbox Code Playgroud)
您运行的命令几乎无关紧要:如果命令本身不需要太多时间,那么就会while导致 CPU 使用率很高。这while :意味着一旦命令结束,循环就会重新启动,一遍又一遍。由于这dd几乎会立即完成,这意味着它会一遍又一遍地启动,每秒多次,因此会占用 CPU 负载。
解决方案是在调用之间添加一个小暂停:
{
while :; do
dd iflag=fullblock iflag=nonblock bs=65536 count=1 2> /dev/null |
redis-cli -x PUBLISH myChannel
sleep 0.1
done
} < myFifo
Run Code Online (Sandbox Code Playgroud)
即使在运行之间添加 0.1 秒的睡眠也会阻止 CPU 过度消耗。
| 归档时间: |
|
| 查看次数: |
1123 次 |
| 最近记录: |