使用 Perl 线程,我如何同时执行我的线程



我需要同时执行~500个线程,下面是我目前开发的代码。我遇到的问题是我的线程一个接一个地执行(不是异步)。

下面的代码基本上通过一个符号循环运行,该循环告诉要执行哪种类型的线程,但我需要它们同时启动。

no warnings;
while ( my $row =
shift( @{$rowcache} )
|| shift( @{ $rowcache = $sth->fetchall_arrayref( undef, $max_rows ) } ) )
{    
my $prod_filter = "perl /home/zad0xlik/qtrack/1.2.v.chain_pg_sputnik.pl @{$row} " . lc(substr(join('', @{$row}), 0, 1)) . "_optsputnik";
@running = threads->list(threads::running);
print "LOOP $in";
print "  - BEGIN LOOP >> NB running threads = "
. ( scalar @running ) . "n";
if ( scalar @running < $nb_process ) {
my $thread = threads->new( sub { system( ${prod_filter} ); } );
#my $thread = threads->new( sub { sleeping_sub($i, @a, @b) });
push( @Threads, $thread );
my $tid = $thread->tid;
print "  - starting thread $tidn";
}
@running = threads->list(threads::running);
print "  - AFTER STARTING >> NB running Threads = "
. ( scalar @running ) . "n";
foreach my $thr (@Threads) {
if ( $thr->is_running() ) {
my $tid = $thr->tid;
print "  - Thread $tid runningn";
}
elsif ( $thr->is_joinable() ) {
my $tid = $thr->tid;
$thr->join;
print "  - Results for thread $tid:n";
print "  - Thread $tid has been joinedn";
}
}
@running = threads->list(threads::running);
print "  - END LOOP >> NB Threads = " . ( scalar @running ) . "n";
$i++;
}
print "nJOINING pending threadsn";
while ( scalar @running != 0 ) {
foreach my $thr (@Threads) {
$thr->join if ( $thr->is_joinable() );
}
@running = threads->list(threads::running);
}

好的。你真的误解了线程在perl中是如何工作的。它们不是轻量级的。你不应该使用其中的 500 个。

。即使你这样做了,线程调用system来运行另一个Perl脚本也是一个糟糕的解决方案。500 个并发需要 500 个处理器才能同时运行。所以无论如何他们都会排队。

如果你真的想做线程,我建议一个工作线程模型,每个核心生成 2 个线程,并将工作队列到它们。

至于所有线程都"同时"开始 - 这里的答案是首先实例化您的线程,然后使用信号量来启动它们。

但我真的建议你问另一个问题,概述你想要完成什么(并提供到目前为止的代码),因为我很确定会有比 500 个线程更好的方法。

特别是 - 我会认为你只想打开一个 exec 文件句柄,并使用IO::Select从你的子进程中读取。

例如:

while ( stuff ) { #e.g. your query
open ( my $data, '-|,' $prod_filter ); 
push @all_filehandles, $data;  
}
my $select = IO::Select -> new ( @all_filehandles ); 
while ( my @readable = $select -> can_read ) {
foreach my $fh ( @readable ) { 
my $line = <$fh>;
print $line;
}
}

无论如何,类似的东西。

最新更新