in reply to win32 threads problem

We could probably re-create something like your code from the snippets posted and the description, but it wouldn't be identical. And if we did, and it ran without error on our systems, and reported back that we couldn't reproduce the error you are getting, that wouldn't help you.

And without you telling use which versions of perl, threads, threads::shared, IO:Socket and the rest you are using, the chances of us reproducing your particular problem are almost nil.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: win32 threads problem
by leonidlm (Pilgrim) on Dec 07, 2008 at 16:36 UTC
    The whole code:
    Declare the needed modules to import use IO::Socket::INET; use threads; use constant TIMEOUT => 5; # Bind arguments passed to the code to variables my $tag = shift; my $cfgFilesDir = shift; my $peerPort = shift; # Open the configuration files directory and create a thread for each +configuration file opendir (CDIR, $cfgFilesDir) or die; my $file; my $thr; while ($file = readdir(CDIR)) { if ($file =~ /.+?\.properties/) { $thr = threads->create(\&sendRequest, $file, 'localhost', $pee +rPort ); } } closedir (CDIR); # Wait till all the threads will finish their work. In the threads sub + I implemented a timeout # mechanism to prevent a infinity loop my @threads; my $thread; my $rc; while (@threads = threads->list()) { foreach $thread (@threads) { if ($thread->is_joinable()) { $rc = $thread->join(); # Send the opcmon # $rc->[0] is the return code. # $rc->[1] is the nodeName the thread worked on. &sendOpcmon($tag, $rc->[0], $rc->[1]); } } # To prevent the hard CPU lookups sleep(1); } # sub sendRequest { my ($msg, $peerAddr, $peerPort) = @_; my $eTime = time() + TIMEOUT; my $host = (split/\./, $msg)[0]; # configure the socket. $MySocket = new IO::Socket::INET->new( PeerPort => $peerPort, Proto => 'udp', PeerAddr => $peerAddr, ); ioctl($MySocket, 0x8004667e, pack("I", 1)); # Send the request. $MySocket->send($msg); # Now we will wait till the server will respond to our request. while(time() < $eTime) { $MySocket->recv($text,128); if($text =~ /OK/) { return [1, $host]; } # Sleep for 2 secs just to free up a %CPU usage sleep 2; } # We reached the timeout, probably no response will arrive. return [0, $host]; } # sub sendOpcmon { my ($tag, $val, $object) = @_; my $cmd = "opcmon $tag=$val -object $object"; #qx{$cmd}; print $cmd."\n"; }
    Module versions you requested:
    perl: v5.8.8 built for MSWin32-x86-multi-thread
    threads: 1.63
    IO:Socket:INET: 1.31
    (all the above modules where installed with the standard activePerl distribution)
    Hope that information will be enough. Thank you!

      I've succeeded in reproducing your error, and the problem turns out to be associated with opendir/readdir/closedir. Regardless of whether the you use globals or lexicals; or whether the directory handle is closed prior to spawning the threads, you get a trap when trying to join the threads. That doesn't make much sense to me, but there we are.

      I have a work around. Replace:

      opendir (CDIR, $cfgFilesDir) or die; my $file; my $thr; while ($file = readdir(CDIR)) { if ($file =~ /.+?\.properties/) { $thr = threads->create(\&sendRequest, $file, 'localhost', $pee +rPort ); } } closedir (CDIR);

      with

      while( my $file = <*.properties> ) { ## Check the glob matches your fi +les! my $thr = threads->create(\&sendRequest, $file, 'localhost', $peer +Port ); }

      And the global destruction problem will probably go away. At least it does here.

      There are other problems in your code that you'll discover if you enable strict.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Thank you. I managed to remove this problem by closing the dir before throwing all these threads. How you debugged it ? How you started to suspect in the first place this is the problem ?
        And again, thanks all who helped.
      After modifying your program so it would run on linux, it dosn't throw an error, but I just connected to a server and printed the filename. You might want to simplify your program, like taking the thread create out of a loop and just create 3 threads, and see if it works. Also what windows version are you using? Older windows like ME don't handle Perl threads well.

      But the best thing to do is upgrade to Perl5.10 and see if it works there.


      I'm not really a human, but I play one on earth Remember How Lucky You Are