2017-01-02 3 views
2

У меня есть скрипт perl, который порождает 3 потока и использует общую очередь для вытягивания заданий. У меня есть файл журнала для каждого потока.Перенаправить STDOUT для определенной темы в Perl

Что я пытаюсь сделать, это перезаписать STDOUT для этого потока, чтобы все действия в этом потоке печатались в файле журнала, а не в терминале.

Когда я начало каждой нити, есть этот

open (STDOUT, '>>', 'log'.$tid.'.txt'); 

Это перезаписывает STDOUT для всех потоков Unfortunatelly, поэтому у меня есть все модули log3.txt.

Как я могу STDOUT только перезаписывать/перенаправлять текущий поток?

Редактировать: Я попытался SELECT и локальный * STDOUT, моя проблема в том, что каждый поток вызывает .exe, который я хочу, чтобы он выводил на измененный STDOUT, и это не происходит с SELECT и LOCAL.

+0

Возможно, вместо того, чтобы пытаться перезаписать STDOUT, вы можете перенаправить вывод .exe с оператором >> как 'system (" program.exe >> log ". $ tid.". txt ");' в каждом потоке соответственно? – Mariusz

+0

Какую модель/модуль вы используете для нарезки? – zdim

+0

Если ваши потоки называют exe, почему бы вместо этого не использовать 'open' и просто прочитать его как дескриптор файла? – Sobrique

ответ

4

STDOUT - переменная Perl, и в качестве переменной Perl она зависит от потока. Вы можете определенно изменить STDOUT, не затрагивая ни одного другого потока.

$ cat a.pl 
use threads; 

for (1..3) { 
    async { 
     my $tid = threads->tid; 
     open(local *STDOUT, '>', "out.$tid.txt") or die $!; 
     sleep(1); 
     print("$_\n"); 
    }; 
} 

$_->join for threads->list; 

$ perl a.pl 

$ grep '.*' *.txt 
out.1.txt:1 
out.2.txt:2 
out.3.txt:3 

Но это не имеет ничего общего с вашей проблемой. Вы хотите связать stdout дочернего элемента, созданного с помощью дескриптора файла. Это не имеет ничего общего с переменными Perl в родительском объекте и не затрагивается потоками.

use IPC::Run3 qw(run3); 

my $tid = threads->tid; 

run3([ 'printf', '%s\n', $tid ], \undef, "out.$tid.txt"); 

или

use IPC::Run qw(run); 

my $tid = threads->tid; 

run([ 'printf', '%s\n', $tid ], \undef, "out.$tid.txt"); 

или

use IPC::Open3 qw(open3); 

my $tid = threads->tid; 

open(local *CHILD_STDIN, '<', '/dev/null') or die $!; 
open(local *CHILD_STDOUT, '>', "out.$tid.txt") or die $!; 
my $pid = open3('<&CHILD_STDIN', '>&CHILD_STDOUT', '>&STDERR', 
    'printf', '%s\n', $tid); 
waitpid($pid, 0); 

(Я не рекомендую IPC :: open3. Это просто слишком низкий уровень для большинства вещей. Это даже относительно сложное для этой простой задачи Я включил его только в том случае, если он связан с Perl.)

 Смежные вопросы

  • Нет связанных вопросов^_^