我需要同时执行~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 $i\n";
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 $tid\n";
}
@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 running\n";
}
elsif ( $thr->is_joinable() ) {
my $tid = $thr->tid;
$thr->join;
print " - Results for thread $tid:\n";
print " - Thread $tid has been joined\n";
}
}
@running = threads->list(threads::running);
print " - END LOOP >> NB Threads = " . ( scalar @running ) . "\n";
$i++;
}
print "\nJOINING pending threads\n";
while ( scalar @running != 0 ) {
foreach my $thr (@Threads) {
$thr->join if ( $thr->is_joinable() );
}
@running = threads->list(threads::running);
}
答案 0 :(得分:0)
行。你真的误解了线程在perl中的工作方式。它们不轻巧。你不应该使用500个。
...即使你这样做,线程调用system
来运行另一个perl脚本也是一个糟糕的解决方案。并发500个并发需要500个处理器才能同时运行。所以无论如何他们都会排队。
如果你真的想要进行线程化,我建议使用worker threads model,每个核心产生2个线程,并为它们排队。
至于所有从“同一时间”开始的 - 这里的答案是首先实例化你的线程,并使用semaphore开始它们。
但我真的建议你提出另一个问题,概述你要完成的任务(并提供目前为止的代码),因为我很确定会有比500线程更好的方法。
特别是 - 我想你只想打开一个exec文件句柄,并使用IO::Select
从子进程中读取。
E.g:
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;
}
}
无论如何都是这样的。