Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl (http://www.velocityreviews.com/forums/f17-perl.html)
-   -   Howto share filehandles between threads? (http://www.velocityreviews.com/forums/t296185-howto-share-filehandles-between-threads.html)

Sako 06-02-2006 01:23 PM

Howto share filehandles between threads?
 
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 06-03-2006 11:50 AM

Re: Howto share filehandles between threads?
 
On Fri, 02 Jun 2006 08:23:07 -0500, Sako <riderjunk@NOSPAMdls.net>
wrote:

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


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 06-05-2006 02:22 PM

Re: Howto share filehandles between threads?
 
zentara wrote:
> On Fri, 02 Jun 2006 08:23:07 -0500, Sako <riderjunk@NOSPAMdls.net>
> wrote:
>
>
>>Any help on how to share a filehandle opened in a thread would be
>>GREATLY appreciated.

>
>
> 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__
>
>
>
>
>
>
>

Thx much!

xhoster@gmail.com 06-05-2006 03:37 PM

Re: Howto share filehandles between threads?
 
Sako <riderjunk@NOSPAMdls.net> wrote:
> 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 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.


> 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.


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


All times are GMT. The time now is 10:53 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.