在后台执行,但限制执行次数

时间:2013-11-18 21:47:12

标签: perl bash background-process

我有一个程序在指定的日志文件上执行某些操作,每次执行都会多次刷新到磁盘。我从perl脚本调用这个程序,它允许你指定一个目录,我在目录中的所有文件上运行这个程序。由于所有的冲洗,这可能需要很长时间。

我想执行该程序并在后台运行它,但我不希望管道长达数千次执行。这是一个片段:

my $command = "program $data >> $log";
myExecute("$command");

myExecute基本上使用system()运行命令,以及其他一些日志记录/打印功能。我想做的是:

my $command = "program $data & >> $log";

这显然会创建一个大型管道。有没有办法限制一次存在多少后台执行(最好使用&)? (我想尝试2-4)。

2 个答案:

答案 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

  1. 启动4个执行槽并保持到最后
  2. 所有广告位从同一数据文件获取输入
  3. 当插槽准备好处理时,它将读取新的条目以进行处理 直到数据文件/队列为空
  4. 执行期间没有可执行的查找,仅在完成所有工作时。
  5. 代码:

    #!/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