2012-01-25 90 views
3

如果在另一篇文章中有明确的例子,请让我知道。我的线程存在交错打印问题。我试图通过在所有线程中使用共享变量来控制我的线程。下面的伪代码突出显示了我的代码给我带来的问题。我已经尝试了一切,让线程等待轮流打印。目前只有少数产出线正在销毁。Perl线程打印不正确

#!/usr/bin/perl                                 
use threads; 
use threads::shared; 

my $PRINTFLAG :shared = 1; 

Run_Threads(); 

sub Do_stuff{ 

    lock($PRINTFLAG); 
    cond_wait($PRINTFLAG) until $PRINTFLAG == 1; 
    $PRINTFLAG = 0; 
    print "$working\n"; 
    $PRINTFLAG =1; 
} 

子产生线程。

sub Run_Threads{ 

    my @threads; 

    for (my $i = 1; $i <= 5; $i++){ 
     push @threads, threads->create(\&Do_stuff); 
    } 

    foreach (@threads){ 
     $_->join; 
    } 
} 
+0

任何时候我听到“线程”和“打印不正确”在同一句话中,我开始感到一种恐惧感。这通常是一件很难做到的事情。 –

回答

5

似乎每个线程都有自己的句柄,因此它自己的输出缓冲区。考虑到Perl文件句柄不能使用threads::shared中的机制共享,这并不令人惊讶。

这意味着您需要在释放锁之前刷新句柄的缓冲区。之前使用->flush->autoflush方法(而不是$|=1;):你能做到这一点明确:

select->flush();  # Flush handle currently default for print. 

或者你可以有Perl每次打印到手柄后自动冲水:

select->autoflush(1); # Autoflush handle currently default for print. 
$| = 1;    # Autoflush handle currently default for print. 

注Perl 5.14,你还需要加载IO::Handle


顺便说一句,

my $PRINTFLAG :shared = 1; 
lock($PRINTFLAG); 
cond_wait($PRINTFLAG) until $PRINTFLAG == 1; 
$PRINTFLAG = 0; 
print "$d\n"; 
$PRINTFLAG =1; 

可以简化为

my $PRINTMUTEX :shared; 
lock($PRINTMUTEX); 
print "$d\n"; 
+0

$ PRINTFLAG不是文件句柄。我只是试图用它来阻止一个线程,而一个完成打印到标准输出。我是否需要打印到文件句柄?内部缓冲是否把我搞砸了?我应该将缓冲区设置为零吗? –

+0

@ zev.kronenberg,Re“$ PRINTFLAG不是文件句柄”,我知道。 – ikegami

+0

@ zev.kronenberg,Re“我需要打印到文件句柄吗?”我想是这样,因为你需要我们的帮助来做到这一点。 ?!?! – ikegami

3

从我的经验线程它好得多/简单易用Threads::Queue

我有两个队列:一个用于运行线程的任务,另一个用于线程的结果。

因此,在我的主线程中,我只是检查结果的队列并从中打印出来。所以没有任何冲突访问结果文件等

+0

我将不得不在未来尝试这个谢谢! –