Connecting Tech Pros Worldwide Forums | Help | Site Map

Howto share filehandles between threads?

Sako
Guest
 
Posts: n/a
#1: Jun 2 '06
I am trying to teach myself perl by writing a program I've been meaning
to implement, so I am pretty green in perl. I'm having problems sharing
filehandles opened by a thread - been RTFM for a few days, but am having
no luck.

I am attempting to write a threaded server program that listens on a
socket for requests, then passes the socket's filehandle to an event
processor routine, while the listener thread keeps on listening.
However, I cannot seem to be able to successfully pass the filehandle
from the listener thread to the event handler.

For testing purposes, I've tried to get the logic down using a thread to
open a filehandle and pass it back to the non-threaded routine as follows:

--------- start ------------
#!/usr/bin/perl

use threads;
use threads::shared;

my $FH : shared;

threads->new(sub {
open($LFH,"< /tmp/junk") || die $!;
$FH=$LFH;
print "[$FH]\n";
#while (<$LFH>) {print "> $_";}
})->join;

print "[$FH]\n";
while (<$FH>) {print "> $_";}

---------- end -------------

Running it gives:
"thread failed to start: Invalid value for shared scalar at ./x.pl line 10."

Any help on how to share a filehandle opened in a thread would be
GREATLY appreciated.

TIA

zentara
Guest
 
Posts: n/a
#2: Jun 3 '06

re: Howto share filehandles between threads?


On Fri, 02 Jun 2006 08:23:07 -0500, Sako <riderjunk@NOSPAMdls.net>
wrote:
[color=blue]
>Any help on how to share a filehandle opened in a thread would be
>GREATLY appreciated.[/color]

Hi, BrowserUk figured it out on perlmonks awhile back, what you
need to do basically is get the fileno of the filehandle, and pass
it around through shared variables.

See:
http://perlmonks.org?node_id=395513


Also of interest may be
http://perlmonks.org?node_id=501725

Here is a little demo I worked up for myself.

#!/usr/bin/perl
use warnings;
use strict;
use threads;
use threads::shared;

my %shash;
#share(%shash); #will work only for first level keys
my %hash;

share ($shash{'go'});
share ($shash{'fileno'});
share ($shash{'pid'});
share ($shash{'die'});

$shash{'go'} = 0;
$shash{'fileno'} = -1;
$shash{'pid'} = -1;
$shash{'die'} = 0;

$hash{'thread'} = threads->new(\&work);

$shash{'go'} = 1;

sleep 1; # cheap hack to allow thread to setup

my $fileno = $shash{'fileno'};
open (my $fh, "<&=$fileno") or warn "$!\n";

while ( <$fh> ){ print "In main-> $_"; }

#wait for keypress to keep main thread alive
<>;

# control-c to exit

################################################## ################
sub work{
$|++;
while(1){
if($shash{'die'} == 1){ return };

if ( $shash{'go'} == 1 ){

my $pid = open(FH, "top -b |" ) or warn "$!\n";
my $fileno = fileno(FH);
print "fileno->$fileno\n";
$shash{'fileno'} = $fileno;

$shash{'go'} = 0; #turn off self before returning
}else
{ sleep 1 }
}
}
################################################## ###################
__END__







--
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html
Sako
Guest
 
Posts: n/a
#3: Jun 5 '06

re: Howto share filehandles between threads?


zentara wrote:[color=blue]
> On Fri, 02 Jun 2006 08:23:07 -0500, Sako <riderjunk@NOSPAMdls.net>
> wrote:
>
>[color=green]
>>Any help on how to share a filehandle opened in a thread would be
>>GREATLY appreciated.[/color]
>
>
> Hi, BrowserUk figured it out on perlmonks awhile back, what you
> need to do basically is get the fileno of the filehandle, and pass
> it around through shared variables.
>
> See:
> http://perlmonks.org?node_id=395513
>
>
> Also of interest may be
> http://perlmonks.org?node_id=501725
>
> Here is a little demo I worked up for myself.
>
> #!/usr/bin/perl
> use warnings;
> use strict;
> use threads;
> use threads::shared;
>
> my %shash;
> #share(%shash); #will work only for first level keys
> my %hash;
>
> share ($shash{'go'});
> share ($shash{'fileno'});
> share ($shash{'pid'});
> share ($shash{'die'});
>
> $shash{'go'} = 0;
> $shash{'fileno'} = -1;
> $shash{'pid'} = -1;
> $shash{'die'} = 0;
>
> $hash{'thread'} = threads->new(\&work);
>
> $shash{'go'} = 1;
>
> sleep 1; # cheap hack to allow thread to setup
>
> my $fileno = $shash{'fileno'};
> open (my $fh, "<&=$fileno") or warn "$!\n";
>
> while ( <$fh> ){ print "In main-> $_"; }
>
> #wait for keypress to keep main thread alive
> <>;
>
> # control-c to exit
>
> ################################################## ################
> sub work{
> $|++;
> while(1){
> if($shash{'die'} == 1){ return };
>
> if ( $shash{'go'} == 1 ){
>
> my $pid = open(FH, "top -b |" ) or warn "$!\n";
> my $fileno = fileno(FH);
> print "fileno->$fileno\n";
> $shash{'fileno'} = $fileno;
>
> $shash{'go'} = 0; #turn off self before returning
> }else
> { sleep 1 }
> }
> }
> ################################################## ###################
> __END__
>
>
>
>
>
>
>[/color]
Thx much!
xhoster@gmail.com
Guest
 
Posts: n/a
#4: Jun 5 '06

re: Howto share filehandles between threads?


Sako <riderjunk@NOSPAMdls.net> wrote:[color=blue]
> I am trying to teach myself perl by writing a program I've been meaning
> to implement, so I am pretty green in perl. I'm having problems sharing
> filehandles opened by a thread - been RTFM for a few days, but am having
> no luck.[/color]

I think Perl is a great language, but not for threading. You should
probably either choose a different task to be your introduction to Perl;
or, if threading is central to what you do, then choose to learn a
different language.

[color=blue]
> I am attempting to write a threaded server program that listens on a
> socket for requests, then passes the socket's filehandle to an event
> processor routine, while the listener thread keeps on listening.
> However, I cannot seem to be able to successfully pass the filehandle
> from the listener thread to the event handler.[/color]

If you are going to start a new thread for each session (which I wouldn't
recommend, but then again I don't recommend this whole situation), then I
wouldn't pass the handle at all. Simply stash the handle in a variable
whose scopes spans both the listener and the event handler. A child thread
glombs onto whatever handle was stored in a variable at the time it was
created. This requires the listener to be the "master" thread.

use strict;
use warnings;
use threads;
use threads::shared;
$|=1;
my $conn;
foreach (1..10) {
undef $conn;
open $conn, ">/tmp/foo_$_" or die $!;
threads->create("do_it", $_);
};
$_->join foreach threads->list();
sub do_it {
my $request=shift;
foreach (1..100)
{
print $conn "$request $_\n";
select undef,undef,undef, 0.1;
};
};

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
Closed Thread