帮助我在打印到输出文件" temp.out"。
时,如何以及在哪里使用信号量来控制? open(OUT,">temp.out");
open(IN,"temp.txt");
while(<IN>)
{
$line = $_;
- &GT;对于每一行,我想使用thread_main做一些工作。
&#34; thread_main - &gt;分支到thread1,thread2,thread3;&#34; thread1对file1.txt执行IO(读取)操作 - 应与sem1同步 线程2对file2.txt执行IO(读取)操作 - 应与sem2同步 thread3对file3.txt执行IO(读取)操作 - 应该使用sem3进行sysn
thread1 -> returns var1
`var1 = thread1->join();` thread2 works on thread1 return data
thread2 -> returns var2
`var2 = thread1->join();` thread3 works on thread2 return data
thread3 -> returns var3
thread3->join();
这些线程最终会出现一些我要打印到文件中的变量。
printf(OUT "%s\t%s\t%s\t%s\n",$var1,$var2,$var3);
- &gt;应该与sem_main同步
}
答案 0 :(得分:1)
你说你想要使用信号量,但我不认为你真的这样做 - 信号量作为并发编程中的一个特定含义,它基本上是一个全球性的旗帜&#39;处理资源和所有权的某种方式和限制。
如果这是您所需要的,那么您可以使用lock
实现基本版本,使用Thread::Semaphore
实现更全功能的版本;
然而,在我看来,你不是,你只是试图整理线程中的数据。
对于单个值 - 只需从标量上下文开始,然后使用return
/ join
。
E.g:
sub worker_thread {
#do stuff;
return $value;
}
my $thr = threads -> create ( \&worker_thread );
#will block until 'thr' finishes.
my $result_from_thread = $thr -> join();
但是,我一般主张使用Thread::Queue
使用enqueue
和dequeue
(以及end
)在线程周围传递值。
my $result_q = Thread::Queue -> new();
sub worker_thread {
my ( $filename ) = @_;
#run loop
#do stuff
$result_q -> enqueue ( $result );
#exit loop
}
#create threads - use a loop if you need several, passing parameters is good too.
foreach my $filename ( @file_list ) {
my $thr = threads -> create ( \&worker_thread, $filename );
}
foreach my $thread ( threads -> list() ) {
$thread -> join();
}
$result_q -> end();
while ( my $result = $result_q -> dequeue ) {
#do something with $result;
}
如果您也拥有大量文件,则可以使用此方法 - 产生大量线程会很快变得昂贵,但您可以创建一个“工作人员”池。线程,并为它们提供队列中的文件名列表。
我建议你考虑为什么你在这里进行线程化。通常进行线程处理是为了避免阻塞调用并获得更多的CPU时间。读取文件是阻止IO的一种形式,但如果它们来自同一存储子系统,那么并行执行3并不一定能让您获得更好的性能。您的限制因素不会是您的CPU /内存,而是您的磁盘旋转速度 - 您无法改进的东西,并且可能会因尝试线程而变得更糟。
答案 1 :(得分:0)
有趣的是我有1个多线程perl,它基于这个逻辑工作。在我所有的线程之后,我执行了2个方法:
sub is_running(){
my $threads_num=0;
foreach (@threads){
if ($_-is_joinable()){
$threads_num++;
}
}
if ( $threads_num == @machines ) {
return 0; # All threads are completed
}
return 1; # Not all threads are completed
}
这个是检查所有线程是否已完成,因为根据您的实现,主线程可以退出而无需等待已经启动的子线程。
my $count=30;
while ((is_running)&&($count 0)){
$count--;
sleep(1);
}
由于我正在使用线程执行ssh命令,如果其中一些线程卡在某处,则会超时。
超时后我称之为这个方法:
sub return_result(){
my $machine_num=0;
foreach (@threads){
if ($_-is_joinable()){
push(@results,$machines[$machine_num].$_-join());
if ( $results[$machine_num] !~ OK){
$rc=1;
}
}else{
my $id=$_-tid();
push(@results,$machines[$machine_num] TIMEOUT);
$_-detach();
$rc=1;
}
$machine_num++;
}
if ( $rc == 0 ) {
$result=The execution of '$com' has returned '$res' on all hosts OK ;
}else{
$result=The execution of '$com' has NOT returned '$res' on some hosts ERROR ;
}
foreach(@results){
$result.=$_;
}
return $result br;
}
基本上它检查一个线程是否可以连接(已完成它的工作)将其结果推送到一个数组。