-2

试图找到一种方法让一个 perl 脚本在 windows 上运行 4 个其他 perl 脚本,然后一旦全部完成,启动第 5 个脚本。我已经检查了很多东西,但似乎没有一个是直截了当的。欢迎提出建议。脚本将在 Windows 框中运行。脚本 1-4 需要在开始脚本 5 之前先完成

4

3 回答 3

1
  1. 接受其他问题的答案

  2. use threads

    2.1。启动 4 个脚本:

    my @scripts = qw(... commands ...);
    my @jobs = ();
    foreach my $script (@scripts) {
      my $job = threads->create( sub {
        system($script);
      });
      push @jobs, $job;
    }
    

    2.2. 等待完成

    $_->join() foreach @jobs;
    

    2.3. 启动最后一个脚本

编辑

正如你指出我的解决方案对你不起作用,我启动了我的 Windoze 盒子,教我使用这个可怕的 cmd.exe 并编写了以下测试脚本。它比上述解决方案稍微简化了一点,但确实满足您对顺序性等的要求。

#!/usr/bin/perl
use strict; use warnings; use threads;

my @scripts = (
  q(echo "script 1 reporting"),
  q(perl -e "sleep 2; print qq{hi there! This is script 2 reporting\n}"),
  q(echo "script 3 reporting"),
);

my @jobs = map {
  threads->create(sub{
    system($_);
  });
} @scripts;

$_->join foreach @jobs;

print "finished all my jobs\n";

system q(echo "This is the last job");

我使用这个命令来执行脚本(在 Win7 上使用 Strawberry Perl v5.12.2):

C:\...>perl stackoverflow.pl

这是输出:

"script 1 reporting"
"script 3 reporting"
hi there! This is script 2 reporting
finished all my jobs
"This is the last job"

那么这到底怎么行不通呢?下次我在非 GNU 系统上编写脚本时,我非常想学习如何规避 Perl 的陷阱,所以请赐教我可能出错的地方。

于 2012-09-11T19:36:52.433 回答
0

根据个人经验,fork()在 ActiveState Perl 中使用并不总是按顺序运行进程。那里使用的线程模拟fork()似乎启动了所有进程,使其达到某个点,然后一次运行一个。这甚至适用于多核 CPU。我认为 Strawberry Perl 的编译方式相同。另外,请记住,fork()它仍然被用于反引号和system(),它只是被抽象掉了。

如果您在 Windows 上使用 Cygwin Perl,它将通过 Cygwin 自己的fork()调用运行,并且事情将正确并行化。但是,Cygwin 在其他方面较慢。

于 2012-09-11T19:49:22.380 回答
0
use Proc::Background;

my @commands = (
  ['./Files1.exe ALL'],
  ['./Files2.exe ALL'],
  ['./Files3.exe ALL'],
  ['./Files4.exe ALL'],
); 

my @procs = map {  Proc::Background->new(@$_) } @commands;

$_->wait for @procs;

system 'echo', 'CSCProc', '--pidsAndExitStatus', map { $_->pid, $_->wait } @procs;

`mergefiles.exe`;
于 2012-09-12T15:18:24.250 回答