使用 Thread::Semaphore。限制线程数

Work with Thread::Semaphore.Limit the number of threads

我无法处理Semapfor。由于他们运行,所以他们通过了一个流?实际上,变量$n Randomnaya取自02。当条件$n = $it(#$num - stream number)时,消息,则流$num抽烟。其他的(# where $ n!= $ Num)应该被跳过。消息"trade does not smoke."的情况是一下子把所有的线程都传过去了,在不需要的地方,他推导出流量$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;
}

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

当您调用 down() 时,计数器会减少 - 如果不能减少,它将阻塞。如果您调用 up(),则计数会增加。 (并且任何阻塞都将被释放)。

但是,在 'block' 发生之前,线程可以 - 并且将会 - 以未定义的顺序执行,您应该假设这是随机的。 (不完全是,但依赖任何特定序列都会产生竞争条件)。

这并不复杂,但 可能 使您陷入困境的其中一件事是缓冲 - 线程中的打印语句可能会被缓冲,因此似乎以奇怪的顺序到达。

例如:

#! 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"; 
}

我认为缓冲是您的代码出了问题的地方 - 试试 $|++