我有一个程序在指定的日志文件上执行某些操作,每次执行都会多次刷新到磁盘。我从perl脚本调用这个程序,它允许你指定一个目录,我在目录中的所有文件上运行这个程序。由于所有的冲洗,这可能需要很长时间。
我想执行该程序并在后台运行它,但我不希望管道长达数千次执行。这是一个片段:
my $command = "program $data >> $log";
myExecute("$command");
myExecute基本上使用system()运行命令,以及其他一些日志记录/打印功能。我想做的是:
my $command = "program $data & >> $log";
这显然会创建一个大型管道。有没有办法限制一次存在多少后台执行(最好使用&)? (我想尝试2-4)。
答案 0 :(得分:2)
#!/bin/bash
#
# lets call this script "multi_script.sh"
#
#wait until there are less then 4 instances running
#polling with interval 5 seconds
while [ $( pgrep -c program ) -gt 4 ]; do sleep 5; done
/path/to/program "$1" &
现在这样称呼:
my $command = "multi_script.sh $data" >> $log;
如果bash脚本等待,你的perl脚本将会等待。
<强>阳性:强> 如果进程崩溃,它将被替换(数据当然是未处理的)
<强>缺点:强> 您的perl脚本在启动实例之间等待一段时间非常重要 (也许是一秒钟的睡眠时间) 因为调用脚本和传递while循环测试之间的延迟。如果你过快地产生它们(系统垃圾邮件),你最终会得到比你讨价还价更多的进程。
答案 1 :(得分:0)
如果你能够改变
my $command = "program $data & >> $log";
到
my $command = "cat $data >>/path/to/datafile";
(甚至更好:直接从perl将$ data附加到/ path / to / datafile)
当你的脚本完成后,最后一行将是:
System("/path/to/quadslotscript.sh");
然后我在这里有脚本quadslotscript.sh
:
代码:
#!/bin/bash
#use the datafile as a queue where all processes get their input
exec 3< "/path/to/datafile"
#4 seperate processes
while read -u 3 DATA; do "/path/to/program $DATA" >>$log; done &
while read -u 3 DATA; do "/path/to/program $DATA" >>$log; done &
while read -u 3 DATA; do "/path/to/program $DATA" >>$log; done &
while read -u 3 DATA; do "/path/to/program $DATA" >>$log; done &
#only exit when 100% sure that all processes ended
while pgrep "program" &>"/dev/null" ; do wait ; done