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]

Reply via email to