首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Perl:执行10个系统进程异步

Perl:执行10个系统进程异步
EN

Stack Overflow用户
提问于 2019-02-18 22:10:23
回答 3查看 505关注 0票数 2

此问题用于在windows 2012服务器上运行perl。

所以我有一个名为Commands_To_Run的文件夹,下面有100个批处理文件。

代码语言:javascript
运行
复制
Commands_To_Run
 - run_1.bat
 - run_2.bat
 - run_3.bat 
...
 - run_100.bat

每个run*.bat文件大约需要30分钟才能完成。如果我使用FOR循环连续运行这些批处理文件,那么运行这些批处理文件需要100 * 30分钟。(太长了!)

我想要的是编写一个perl脚本,它将一次执行10个批处理文件。一旦任何一个批处理文件完成,下一个批处理文件将被执行。

例如,我希望通过run10.bat执行run1.bat。假设run7.bat完成,那么我想运行下一个run11.bat,以此类推。因此,有10个文件运行在任何给定的时间。

我考虑过使用这个perl脚本来运行批处理文件,但这将同时运行所有100,并且它将扼杀我的windows CPU & processing。

代码语言:javascript
运行
复制
for ($x=0; $x < scalar(@files); $x++ ) {
    $file=@files[$x];
    chomp $file;
    $cmd="start $file ";
    print "Runnung Command is: $cmd\n";
    system($cmd);
}

我查看了所给出的建议,但没有关于如何使用Forks::Super的实用示例。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-02-18 22:47:14

在并行和队列中运行进程的一种简单方法是使用并行::ForkManager

代码语言:javascript
运行
复制
use warnings;
use strict;
use feature 'say';

use Parallel::ForkManager;    

my $pm = Parallel::ForkManager->new(10); 

# Prepare the list of your batch files (better get names from disk)
my @batch_files = map { "Commands_To_Run/run_$_.bat" } 1..100;

foreach my $batch_file (@batch_files)
{
    $pm->start and next;
    # Run batch job
    say "Running: $batch_file";
    #system($batch_file);        # uncomment to actually run the jobs
    $pm->finish;
}
$pm->wait_all_children;

这是一个很小但很有效的脚本。例如,请参阅这个职位这个职位,以获得有关作业进行方式的更多信息,特别是有关如何从作业返回数据的信息。

注意:这不是一个核心模块,所以您可能需要安装它

票数 3
EN

Stack Overflow用户

发布于 2019-02-19 06:11:57

并行::ForkManager依赖于fork,这是Unix系统的一个特性,在Windows系统上Perl (使用线程)很难模仿它。我建议直接使用线程。越少越容易出错。

代码语言:javascript
运行
复制
use threads; 
use Thread::Queue 3.01 qw( );

sub worker {
   my ($command) = @_;
   system($command);
}

{
   my $q = Thread::Queue->new();
   for (1..10) {
      async {
         while (my $job = $q->dequeue()) {
            worker($job);
         }
      }
   }

   $q->enqueue($_) for @commands;
   $q->end();
   $_->join for threads->list;
}
票数 1
EN

Stack Overflow用户

发布于 2019-02-19 07:28:21

只是把它放在那里,但也可以用批处理文件执行,这应该循环遍历所有.bat文件,检查进程计数,如果进程不少于或等于9(如果进程不少于或等于9,它仍然会启动一个进程):

代码语言:javascript
运行
复制
@echo off
setlocal enabledelayedexpansion
set cnt=1
for %%i in (*.bat) do (
    set id=%%i
    call :check
)

:check
for /f "tokens=1,*" %%a in ('tasklist /FI "WINDOWTITLE eq _process*" ^| find /I /C "cmd.exe"') do set procs=%%a
    if !procs! leq 9 (
    if not "!id!"=="%0" start "_process!cnt!" !id!
    set /a cnt+=1
   ) else (
     goto check
 )
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54756117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档