Perl线程无法正确打印

zev*_*erg 3 printing perl file-io multithreading

如果在另一篇文章中有明确的例子,请告诉我.我遇到了来自我的线程的交错打印问题.我试图通过在所有线程中使用共享变量来控制我的线程.下面的伪代码突出显示了我的代码片段给我带来的问题.我已经尝试了一切让线程轮流等待打印.现在只有少数输出线被销毁.

#!/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;
}
Run Code Online (Sandbox Code Playgroud)

Sub生成线程.

sub Run_Threads{

    my @threads;

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

    foreach (@threads){
        $_->join;
    }
}
Run Code Online (Sandbox Code Playgroud)

ike*_*ami 5

似乎每个线程都有自己的句柄,因此它有自己的输出缓冲区.考虑到使用threads :: shared中的机制无法共享Perl文件句柄,这并不奇怪.

这意味着您需要在释放锁之前刷新句柄的缓冲区.你可以明确地做到这一点:

select->flush();       # Flush handle currently default for print.
Run Code Online (Sandbox Code Playgroud)

或者,您可以在每次打印到该句柄后自动刷新perl:

select->autoflush(1);  # Autoflush handle currently default for print.
$| = 1;                # Autoflush handle currently default for print.
Run Code Online (Sandbox Code Playgroud)

注意:要在Perl 5.14之前使用->flush->autoflush方法(但不是for $|=1;),您还需要加载IO :: Handle.


顺便说说,

my $PRINTFLAG :shared = 1;
lock($PRINTFLAG);
cond_wait($PRINTFLAG) until $PRINTFLAG == 1;
$PRINTFLAG = 0;
print "$d\n";
$PRINTFLAG =1;
Run Code Online (Sandbox Code Playgroud)

可以简化为

my $PRINTMUTEX :shared;
lock($PRINTMUTEX);
print "$d\n";
Run Code Online (Sandbox Code Playgroud)