Потоки Perl печатаются неправильно - PullRequest
3 голосов
/ 25 января 2012

Если в другом посте есть явные примеры, пожалуйста, дайте мне знать.У меня проблемы с чередованием печати из моих тем.Я пытаюсь контролировать свои потоки с помощью общей переменной во всех потоках.Приведенный ниже псевдокод выделяет фрагменты моего кода, которые вызывают у меня проблемы.Я перепробовал все, чтобы заставить нити ждать своей очереди на печать.Прямо сейчас только несколько выходных линий разрушаются.

#!/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 to spawn threads.

sub Run_Threads{

    my @threads;

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

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

Ответы [ 2 ]

5 голосов
/ 25 января 2012

Казалось бы, у каждого потока есть свой дескриптор и, следовательно, собственный выходной буфер. Учитывая, что дескрипторы файлов Perl нельзя использовать совместно с помощью механизмов threads :: shared , это не очень удивительно.

Это означает, что вам нужно очистить буфер дескриптора перед снятием блокировки. Вы можете сделать это явно:

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.

Примечание. Чтобы использовать методы ->flush и ->autoflush (но не для $|=1;) до 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";
3 голосов
/ 25 января 2012

Из моего опыта работы с потоками гораздо удобнее / проще в использовании Темы :: Очередь .

У меня есть две очереди: одна для задач для запуска потоков и другая для результатов от потоков.

Итак, в моем основном потоке я просто проверяю очередь результатов и печатаю из нее. Так что никаких конфликтов при доступе к файлу результатов и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...