使用Thread :: Semaphore.Limit线程数

时间:2016-05-25 05:49:08

标签: multithreading perl semaphore

我无法处理Semapfor。当他们跑,所以他们传递了一个流?实际上,变量$ n Randomnaya取自 0 2 。当$ n = $ it(#$ num - stream number)的条件,消息,然后流$ num抽烟。其他(#where $ n!= $ Num)应该被跳过。消息“交易不吸烟”。情况是它一次传递所有线程并且没有必要,他推断流$ num抽烟(#实际上给出正确的数字,但它不适合这种情况)。

#! usr/bin/perl -w
use strict;
use warnings;
use 5.010;
use threads;
use threads::shared;
use Thread::Semaphore;


my $sem = Thread::Semaphore->new(1);
my $n   = int rand(3);
say $n;
my $shr : shared = 1;
my $threads = 2;
my @threads;

for my $t ( 0 .. $threads ) {
   push @threads, threads->create( \&smoke, $t );
}
# Дожидаемся окончания работы всех потоков
for my $t (@threads) { $t->join(); }


sub smoke {
   my $num = shift;

   $sem->down;
   say "+Thread $num started";
   sleep 1;
   if ( $num = $n ) { sleep 2; say "Thread $num -- smoke"; }
   say "-Thread $num done. \n";

   if ( $num != $n ) {
      say "-Thread $num dont smoke!. \n";
   }
   { lock($shr); $shr++ }
   $sem->up;

   return;
   sleep 1;
}

1 个答案:

答案 0 :(得分:0)

信号量并不比共享计数器复杂。

当您致电down()时,计数器会减少 - 如果不能,则会阻止。如果您致电up(),则计数会增加。 (任何阻止的东西都将被释放)。

但是,直到那个'阻止'发生时,线程可以 - 并且将 - 以未定义的顺序执行,您应该假设它是随机的。 (这不是完全的,但依赖于任何特定的序列都会造成竞争条件。)

它并不复杂,但可以绊倒你的东西之一就是缓冲 - 线程中的print语句可能会被缓冲,所以看起来很奇怪。

E.g:

#! usr/bin/perl -w
use strict;
use warnings;
use 5.010;
use threads;
use threads::shared;
use Thread::Semaphore;


my $sem = Thread::Semaphore->new(1);
#turn off buffering
$|++;

sub wait_for_sem {
   print threads -> self -> tid. ": waiting for semaphore\n"; 
   $sem -> down(); 
   print threads -> self -> tid. ": got semaphore\n"; 
   sleep rand 3;
   print threads -> self -> tid. ": releasing semaphore\n"; 
   $sem -> up; 

}

threads -> create ( \&wait_for_sem ) for 1..100; 
foreach my $thr ( threads -> list ) { 
   print "Waiting for ".$thr->tid." to join\n"; 
   $thr -> join;
   print "Joined ".$thr->tid."\n"; 
}

我认为缓冲是代码出错的原因 - 请使用$|++进行尝试。