Howto share filehandles between threads?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Sako

    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

    #2
    Re: Howto share filehandles between threads?

    On Fri, 02 Jun 2006 08:23:07 -0500, Sako <riderjunk@NOSP AMdls.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.

    Comment

    • Sako

      #3
      Re: Howto share filehandles between threads?

      zentara wrote:[color=blue]
      > On Fri, 02 Jun 2006 08:23:07 -0500, Sako <riderjunk@NOSP AMdls.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!

      Comment

      • xhoster@gmail.com

        #4
        Re: Howto share filehandles between threads?

        Sako <riderjunk@NOSP AMdls.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,und ef, 0.1;
        };
        };

        Xho

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

        Comment

        Working...