By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,219 Members | 1,110 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,219 IT Pros & Developers. It's quick & easy.

Howto share filehandles between threads?

P: n/a
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
Jun 2 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
On Fri, 02 Jun 2006 08:23:07 -0500, Sako <ri*******@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
Jun 3 '06 #2

P: n/a
zentara wrote:
On Fri, 02 Jun 2006 08:23:07 -0500, Sako <ri*******@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!
Jun 5 '06 #3

P: n/a
Sako <ri*******@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
Jun 5 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.