所以我有这样的事情:
fork.pl
for $str (@files)
{
my($command) = "perl command.pl ".$str;
exec( $command );
}
command.pl
$file=$ARGV[0].".csv";
#code that counts rows here
print $rowcount;
因此,最终结果是我启动了10个文件来计算每个csv文件中的行数。
我不需要帮助编辑此代码,它可以工作(这只是一个压缩版本)。我需要帮助找出如何获取十个文件的输出($ rowcount)并将其合并为一个文件以便进一步处理。
答案 0 :(得分:3)
我为此目的保留了一些实用程序代码...这会稍微调整一下你的问题并包括一个同步的全局计数方法。
#!/usr/bin/perl
use threads;
use Thread::Queue;
my @workers;
my $num_threads = 10;
my $queue = new Thread::Queue;
my $total_ines = 0;
for (0..$num_threads-1) {
$workers[$_] = new threads(\&worker);
}
while ($_ = shift @ARGV) {
$queue->enqueue($_);
}
sub worker() {
while ($file = $queue->dequeue) {
#line counting code here
global_counter($lines_counted);
}
}
sub global_counter() :locked {
#add to the number of lines counted
$total_lines += shift
}
for (0..$num_threads-1) { $queue->enqueue(undef); }
for (0..$num_threads-1) { $workers[$_]->join; }
print $total_lines;
答案 1 :(得分:2)
使用管道解决这种通信(让我写一个简单的例子):
# -- fork.pl -------------------------
for (1..3) {
open my $PIPE, "perl command.pl |";
print "catch: $_\n" while(<$PIPE>);
close $PIPE;
}
# -- command.pl ----------------------
print rand(1);
打印(随机数):
catch: 0.58929443359375
catch: 0.1290283203125
catch: 0.907012939453125
答案 2 :(得分:0)
你需要查看线程或进程间进程与例如使用fork时的套接字或共享内存。
答案 3 :(得分:0)
压缩但不起作用。我假设在fork.pl中,你在exec'ing之前分叉?反引号捕获被调用进程的输出,即你的打印: fork.pl
for $str (@files)
{
my($command) = "perl command.pl ".$str;
print `$command`;
}
但是,不是分叉和启动流程,将第二个文件转换为模块会不会更聪明?
package MyCommand;
use Exporter;
our @EXPORT = qw( command );
sub command {
my $file = $_[0] . '.csv';
...
return $rowcount;
}
1;
fork.pl:
use MyCommand;
...
my @rowcounts;
for my $str (@files) {
push @rowcounts, command($str);
}
一些自我推销,但我刚刚在你的另一个帖子中发布了这个,这似乎足够相关:How to run in parallel two child command from a parent one?
答案 4 :(得分:0)
累积儿童的管道:
#!/usr/bin/perl -w
use strict;
my $files = qw/one.csv two.csv three.csv/;
my $command = "perl command.pl";
my @pipes;
foreach (@files) {
my $fd;
open $fd, "-|", "$command $_" and push @pipes, $fd;
};
my $sum = 0;
foreach my $pp (@pipes) {
$sum += $_ if defined ($_=<$pp>);
};
print $sum;
然后您可以逐个读取它们(如示例中所示),或use IO::Select
读取每个管道中显示的数据。
如果您想知道哪些数据来自哪个来源,那么除了数组之外的哈希表也很好。