From: "Beau E. Cox" <[EMAIL PROTECTED]> > I am developing a perl 5.8 application using the > new threading model. I use this technique > (thanks Jenda!) to dup STDIN to a temp file handle: > ... > open SAVIN, '<&STDIN'; > open (STDIN,'<&' . $tmpfh->fileno) or die "..."; > my $out = `some-command 2>&1`; > open STDIN, '<&SAVIN'; > close $tmpfh; > ... > in various threads. All works - the command run > reads from STDIN and output to STDOUT (maybe > STDERR also). I get the output in $out. > > My question: how 'global' is STDIN? Must I place > a lock on some dummy shared variable when using > STDIN in a thread, in other words, will all > threads 'see' the dup of STDIN?
I'm afraid the behaviour of "dup"ing may be operating system dependent. Therefore it might be better to use either the select(OTHER) or local(*STDOUT) way. I tried the attached script on my computer (Win2k server) and all three ways behaved well (the redirection was thread specific) in both Active Perl 631 and 804. HTH, Jenda P.S.: For those not aware of that: fork() creates a new THREAD, not a new process under Windows. I wanted to test this on both 5.6.1 (6xx) and 5.8 (8xx) therefore I had to use this way of creating threads. The threads.pm was not available with 5.6.1. If you use a different OS you will want to convert the code to the threads.pm style. And yes, you are right, I've never worked with threads.pm. I wrote several multithreaded windows services using fork() so it was easier for me to write the code like this. ===== [EMAIL PROTECTED] === http://Jenda.Krynicky.cz ===== When it comes to wine, women and song, wizards are allowed to get drunk and croon as much as they like. -- Terry Pratchett in Sourcery
use strict; $|=1; print "Before fork() : $$\n"; my $pid = fork(); if (!defined $pid) { print "failed to fork()\n"; } elsif ($pid) { print "parent started : $$\n"; sleep(1); # to make sure both threads had time to print the "started" message parent_select(); # parent_local(); # parent_dup(); print "parent finished : $$\n"; } else { print "child started : $$\n"; sleep(1); # to make sure both threads had time to print the "started" message child(); print "child finished : $$\n"; } sub child { sleep(2); print "NOT redirected child : $$\n"; sleep(4); } sub parent_select { # thread-local { # redirect open my $OUT, '> test.txt' or die "Can't write to test.txt : $!\n"; select($OUT); print "redirected parent : $$\n"; sleep(4); select(STDOUT); close $OUT; } # redirect back } sub parent_local { # thread-local { # redirect local *STDOUT; open STDOUT, '> test.txt' or die "Can't write to test.txt : $!\n"; print "redirected parent : $$\n"; sleep(4); close STDOUT; } # redirect back } sub parent_dup { # thread-local { # redirect open my $OUT, '>&STDOUT' or die "Can't dup STDOUT : $!\n"; close(STDOUT); open STDOUT, '> test.txt' or die "Can't write to test.txt : $!\n"; print "redirected parent : $$\n"; sleep(4); close(STDOUT); # open STDOUT, ">&", $OUT or die "Can't restore STDOUT : $!\n"; # 5.8 only open STDOUT, ">&" . fileno($OUT) or die "Can't restore STDOUT : $!\n"; close $OUT; } # redirect back }
-- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]