[ale] Another Perl + Threads question

Christopher Fowler cfowler at outpostsentinel.com
Wed Apr 27 01:22:03 EDT 2005


I've not been able to get data shared correctly between the threads to I
wrote this test app to see if I can get it to work


                                                                                                                                                                                   
      3 use Console;
      4 use IO::Select;
      5 use threads;
      6 use threads::shared;
      7 use Data::Dumper;
      8 use strict;
      9
     10
     11 my %DEVICES = ();
     12 my $selector = new IO::Select;
     13
     14
     15 $DEVICES{1}{'console'} = Console->new('192.168.2.120', 'MBX',
'ensign', 'password');
     16 $DEVICES{1}{'console'}->connect() or die "$!\n";
     17 $selector->add($DEVICES{1}{'console'}->getSocket());
     18
     19 share %DEVICES;
     20
     21 my $last = time();
     22
     23 while(1) {
     24   my $timeout = 10;
     25   my ($rr, undef, $er) = IO::Select->select($selector, undef,
$selector, $timeout) ;
     26
     27   foreach my $fh (@$rr) {
     28     foreach my $ref (sort keys %DEVICES) {
     29       $ref = $DEVICES{$ref};
     30       next unless defined $ref->{'console'};
     31       next unless $ref->{'console'}->getSocket() == $fh;
     32       my $data = "";
     33
     34       if(sysread($fh, $data, 1) == 0) {
     35         die;
     36         #eof;
     37         print "EOF from console\n";
     38         $selector->remove($fh);
     39         undef $ref->{'console'};
     40         next;
     41       }
     42
     43       syswrite STDOUT, $data, 1;
     44     }
     45   }
     46
     47   my $now = time();
     48
     49   if(($now - $last) >= 20) {
     50     print "Need to check dead hosts";
     51     foreach my $ref (sort keys %DEVICES) {
     52       $ref = $DEVICES{$ref};
     53       next if defined $ref->{'console'};
     54       print "Need to try and reconnect to console!\n";
     55       async {
     56         $ref->{'console'} =
     57          Console->new('192.168.2.120', 'MBX', 'ensign',
'password');
     58
     59         do {
     60           undef $ref->{'console'};
     61           next;
     62         } unless $ref->{'console'}->connect();
     63         $selector->add($$ref->{'console'}->getSocket());
     64       };
     65     }
     66     $last = $now;
     67   }
     68 }
     69


In line 19 after I execute share() it seems that I've lost all the data
in %DEVICES.  Data::Dumper Sees nothing.  The whole reason for threads
here is to protect the program from blocking in the code that goes after
dead devices and tries to connect.  It could take many seconds before a
connect() fails so if the program spends to long trying to cycle through
a list of dead hosts trying to reconnect it could be a few minutes
before it gets back to the select.  I thought it would be a great idea
to place each dead host into its own thread.  I could create one worker
thread that cycles through the list at all times.

If I move the share statement to line 14 before I make all the
connections I get the following error:

[tomcat at sam-devel cfowler]$ ./threadtest.pl
Invalid value for shared scalar at ./threadtest.pl line 16.

I read in perlthrtut that blessed objects can not be shared?  Is this
true?  Even the simplest object like this:

$VAR1 = '1';
$VAR2 = {
          'console' => bless( {
                                'password' => 'password',
                                'user' => 'ensign',
                                'console' => 'MBX',
                                'server' => '192.168.2.120',
                                'logfilename' =>
'consoles/192.168.2.120/MBX',
                                'logfile' => undef,
                                'sock' => bless( \*Symbol::GEN1,
'IO::Socket::INET' )
                              }, 'Console' )
        };
 

Has embedded blessed objects.

Can someone that has done threads in Perl let me know how I can write
this test program to work with threads with the goal of moving all the
reconnect code into threads.

Thanks,
Chris






More information about the Ale mailing list