Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^2: win32 threads problem

by leonidlm (Pilgrim)
on Dec 07, 2008 at 16:36 UTC ( [id://728738]=note: print w/replies, xml ) Need Help??


in reply to Re: win32 threads problem
in thread win32 threads problem

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!

Replies are listed 'Best First'.
Re^3: win32 threads problem
by BrowserUk (Patriarch) on Dec 07, 2008 at 22:43 UTC

    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.
        I managed to remove this problem by closing the dir before throwing all these threads.

        Hm. I tried that here and it didn't effect a cure reliably. It would sometimes (mostly), work with small numbers of files (threads), but if I asked it to run a couple of hundred threads it always failed during globals destruction.

        But when I used a glob, the problem disappeared. (I'll have another go later to confirm my findings!)

        As for how to debug it, the watchword with threads is pretty much always the same: simplify.

        First I tried a non-threaded version. No trap. Then a one threaded. No trap. Then 10 threads--trap.

        So then I tried simplifying the thread proc. Take out everything except

        sub threads { my ($msg, $peerAddr, $peerPort) = @_; sleep 1; return [1, $msg]; }

        Still traps, so look outside. Replaced the while( readdir ) with while( <DATA> ) { and a list of files that caused a trap and the trap went away.

        Put back the full thread proc and a larger DATA section, trap still didn't happen.

        Put back the opendir/readdir/closedir. Trap returns.

        Try glob. trap disappears again. Bingo!

        Update: I just tried building the file list using opendir/readdir/closedir first, and then starting the threads again, and this time it worked fine. Maybe I missed that combination last night.


        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.
Re^3: win32 threads problem
by zentara (Archbishop) on Dec 07, 2008 at 17:51 UTC
    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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://728738]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2024-04-19 13:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found