Howto share filehandles between threads?

Discussion in 'Perl Misc' started by Sako, Jun 2, 2006.

  1. Sako

    Sako Guest

    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, Jun 2, 2006
    #1
    1. Advertising

  2. Sako

    Sako Guest

    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!
    Sako, Jun 5, 2006
    #2
    1. Advertising

  3. Sako

    Guest

    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
    , Jun 5, 2006
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sako
    Replies:
    3
    Views:
    5,597
  2. Saraswati lakki
    Replies:
    0
    Views:
    1,287
    Saraswati lakki
    Jan 6, 2012
  3. Jorge
    Replies:
    3
    Views:
    111
    Dr.Ruud
    Apr 11, 2007
  4. PerlFAQ Server
    Replies:
    0
    Views:
    182
    PerlFAQ Server
    Jan 12, 2011
  5. Replies:
    0
    Views:
    72
Loading...

Share This Page