我无法处理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;
}
答案 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";
}
我认为缓冲是代码出错的原因 - 请使用$|++
进行尝试。