简体   繁体   中英

Redirect STDOUT for a specific thread in Perl

I have a perl script that Spawns 3 threads, and uses a shared queue to pull jobs. I have a log file for each thread.

What I am trying to do is to overwrite STDOUT for this thread, so that all actions within this thread prints to the log file and not the terminal.

When I initiate each thread, have this

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

This overwrites STDOUT for all threads unfortunatelly, so I have everything ins log3.txt.

How can I have STDOUT only overwritten/redirected for the current thread?

Edit: I did try SELECT and local *STDOUT, my problem is, each thread calls an .exe that I want it to output to the modified STDOUT, and that does not happen with SELECT and LOCAL.

STDOUT is a Perl variable, and as a Perl variable, it's thread-specific. You can most definitely change STDOUT without affecting any other threads.

$ 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

But that has nothing to do with your problem. You want to associate the stdout of child you create with a file handle. That has nothing to do with Perl variables in the parent, and isn't affected by threads.

use IPC::Run3 qw( run3 );

my $tid = threads->tid;

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

or

use IPC::Run qw( run );

my $tid = threads->tid;

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

or

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);

(I recommend against IPC::Open3. It's just too low-level for most things. It's even relatively complicated for this simple task. I only included it because it's bundled with Perl.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM