![]() |
|
|
|||||||
![]() |
PERL - Howto share filehandles between threads? |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
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 Sako |
|
|
|
|
#2 |
|
Posts: n/a
|
On Fri, 02 Jun 2006 08:23:07 -0500, Sako <>
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 |
|
|
|
#3 |
|
Posts: n/a
|
zentara wrote:
> On Fri, 02 Jun 2006 08:23:07 -0500, Sako <> > 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! |
|
|
|
#4 |
|
Posts: n/a
|
Sako <> 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 |
|