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]