jwetherill has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,

I have a simple server that creates a thread on an accept. At the accept I create a thread that reads from the socket and does a command, after the command I detach the thread and clean up all the variables, thread finished. back in the main thread I am still waiting for the next accept. On recieving the next accept I have lost a dll that is loaded initialy as part of a use of a module.

so the question is why does it lose the module and what can I do about reloading it, ect.

this is the error that I get on when the second set of threads are created.

0: thread connect Connection Status = Connected (8192) Hangup start Hangup completed successfully 1: thread connect thread failed to start: Win32::RASE: RasDial not found in rasapi32.dll at thread_check.pl line 24 Hangup start thread failed to start: Win32::RASE: RasHangUp not found in rasapi32.d +ll at thread_check.pl line 41
this is the code that I am using to connect and diconnect a modem in a threaded model(simplified) ,
use IPW::NET::Modem; use threads; use threads::shared; my $cxnid; share($cxnid); my $l = shift; for ( my $i = 0; $i < $l ; $i++ ) { print "$i:\n"; threads->create( \&threadConnect )->detach; sleep 30; #give the modem time to connect threads->create( \&threadDisconnect ); sleep 20; #give the modem time to disconnect } sleep 40; sub threadConnect { print "thread connect\n"; $cxnid = Win32::RASE::RasDial("UE01", undef, "jwetherill", "abc123 +", undef, undef); if ( !$cxnid ) { print "Failed to connect\n"; } else { sleep 15; ( $status, $statustext ) = Win32::RASE::RasGetConnectStatus($c +xnid); print "Connection Status = $statustext ($status)\n"; } threads->self->detach; } sub threadDisconnect { print "Hangup start\n"; if ( Win32::RASE::RasHangUp($cxnid, 30) ) { print "Hangup completed successfully\n"; } else { print "Hanging up all active connections\n"; Win32::RASE::HangUp(); } threads->self->detach; }

edit (broquaint): added formatting
edit (holli): added readmore tags

Replies are listed 'Best First'.
Re: loss of dll in a multi threaded app
by BrowserUk (Patriarch) on Jul 04, 2005 at 14:37 UTC

    Your problem description is rather too vague to allow an answer.

    What error are you getting that is causing you to believe that you have "lost a dll"? What is the line of code that produces that error?

    The best way to get help with your problem, is to reduce it to a minimal testcase and post the code, That way we can try it out and see if the problem can be recreated outside of your environment. We will also be able to see what mistakes you are making (if any).


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
Re: loss of dll in a multi threaded app
by zentara (Cardinal) on Jul 04, 2005 at 15:21 UTC
    As a temporary fix, why not just put "finished threads" to sleep, and reuse them for the future "accepts"? It would probably be more efficient too, rather than constantly creating new threads. (But I think your problem is windows.. :-) )

    I'm not really a human, but I play one on earth. flash japh
      could you give me a short example of reuseing the threads, as I have not seen any.

        Apache uses that model. It starts up a number of web server processes. When a request comes in, the main process forwards the request to one of the idle child processes*. It handles the request then waits to be asked to process another.

        * I think this is optimized such that the implementation -- but not the effect -- differs from the above explanation.

        a trick would be to give each worker thread a shared "control" variable that is only used by that thread and the main thread. The main thread takes a lock on the variable, and the worker thread then tries to take a lock on it as well, which will block(put the thread to sleep) until the main thread uses cond_signal(part of threads::shared) to release the lock and hence wake up the worker thread. One might even configure said control variable to contain something useful, ie a filehandle that the worker thread needs to start working on.


        Remember rule one...
        The hash variables below are used so I can have multiple threads waiting in a sleep state for use. The trick to using threads this way, is knowing that they must go to the end of their code block, before joining them. 'go' = 1 wakes them from sleep, and 'die' = 1 signals them to prepare to be joined. It's basically a sleep loop, which wakes up every second, and see's if there is anything to do, or if it's time to die. When done with it's task, it just goes back to sleep. If you know how many max threads you need, you can pre-create them, and track them in some sort of "free-pool", so when you need a thread, it can shift one off of the free-pool-array, and when a thread is finished, push it onto the free-pool-array.

        See Tk-with-worker-threads and Threads-w-Perl/Gtk2 demo for full working examples.

        sub work{ my $dthread = shift; $|++; while(1){ if($shash{$dthread}{'die'} == 1){ goto END }; if ( $shash{$dthread}{'go'} == 1 ){ #in case I want to pass it code for evaling eval( system( $shash{$dthread}{'data'} ) ); # a simple little task foreach my $num (1..100){ $shash{$dthread}{'progress'} = $num; print "\t" x $dthread,"$dthread->$num\n"; select(undef,undef,undef, .5); if($shash{$dthread}{'go'} == 0){last} if($shash{$dthread}{'die'} == 1){ goto END }; } $shash{$dthread}{'go'} = 0; #turn off self before returning }else { sleep 1 } } END: }

        I'm not really a human, but I play one on earth. flash japh
Re: loss of dll in a multi threaded app
by BrowserUk (Patriarch) on Jul 04, 2005 at 17:54 UTC

    Try adding strict and warnings to your script and I think (but can't test as I don't have the requisite module) that this line

    $cxnid = Win32::RASE::RasDial("UE01", undef, "jwetherill", "abc123 +", undef, undef);

    will issue an error: "Invalid value for shared scalar at ... ";

    The problem is that you are trying to share objects (blessed references) across threads, and that is not allowed.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.