in reply to Re^2: multi thread problem in an simple HTTP server
in thread multi thread problem in an simple HTTP server

Okay. Let's get the easy ones out the way first.

  1. Typo. Fair enough, we all make those--especially me. But ...

    With the typo, you aren't locking anything, so the conclusions you have drawn on the basis that you thought that you were doing locking, are now invalid.

  2. Nested subroutines. "for convenience"

    In Perl, subroutines declared within a nested scope are:

    • compiled when the file is loaded;
    • visible outside the subroutine in which they are declared;
    • callable immediately they have been compiled (from anywhere);

    In other words, nesting them serves no purpose other than confusion. It creates expectations in those that do not know the above that their scope is limited. It creates confusion that observers (eg. me), think that the author of the code (eg. you), may believe that their scope is limited.

    The bottom line is that I don't see any convenience; just a source of confusion.

  3. END{} blocks.

    Okay. I learnt something new also :)

  4. Signal handler:

    The problem here is this:

    while ( !$stat{'done'} ) { if ( my $msg = $queue_up->dequeue() ) {

    That loop spends most of its time on the second of those two lines. Waiting to dequeue() a message from the queue. But dequeue() is a blocking call, so it won't get back to the top of the loop to check $stat{done} until a message is received.

    The solution is to use dequeue_nb() (nb for no block). That will ensure that the terminating condition is checked frequently. However, you will also want to add a short sleep to prevent the loop from thrashing the cpu.

    while ( !$stat{'done'} ) { if ( my $msg = $queue_up->dequeue_nb() ) { ... } else { sleep 1; ## Use usleep or select for better responsiveness } }
  5. the biggest problem is in the code:

    I'll come back to this in a separate reply.

  6. Also moved to a separate reply as there is a lot to deal with.

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^4: multi thread problem in an simple HTTP server
by bravesoul (Initiate) on Apr 12, 2009 at 15:58 UTC
    Thanks so much, I am really deeply shocked at your quick and detailed warm hearted reply. I was spending the weekend with my family, sorry for my delayed response. The environment on my notebook at home is different, which with windows xp home edition, and ActiveState Perl v5.10.0 built for MSWin32-x86-multi-thread, so I will do more test when I at work, and make a much more detailed response.
    1. What a shame that I made a typo to such fundamental element. Once I correct it, I can receive the resonse, though it is very slow. When I set $cnf{'timeout'} to 1s it spends about 5s to response, and if I set to 10s it spends about 30s. I will make the same test on my previous environment.

      What a pity, it can't work with the environment Windows 2000 and ActiveState Perl v5.8.6 built for MSWin32-x86-multi-thread. I need to find out what causes the different behavior, the OS or Perl, or both. When I do the same test with ActiveState Perl v5.10.0 built for MSWin32-x86-multi-thread, it is the same, so I think my pre-thread design can't work in Windows 2000. I still can't find out the real reason, but I would like to find a available design works perfectly first, and then to dig further step by step.

    2. I agree with you on eliminating the nested subroutines, the clear and straightforward program will make life easier.
    3. Your signal handler solution works, but it cause the response slower, about 1 minute with the timeout value as 10s. Strange behavior. I have a different solution to this problem: let the worker threads (or a deticated one) periodically notify the main thread with a "heart beat" message, so the main thread will not block at the dequeue operation, and we can also monitor the activity of the other threads. Again I will make the test tomorrow.
    4. I have very little experience in lock/unlock shared variable, I need to learn more about it. I will response for it when I finished doing a lot test.
    5. I use Thread::Queue because it is straightforward, the single entry point does the hard work, such as lock/unlock, wait/signal/broadcast, which prevent me from making mistake on such technology.
    6. I think I need to find some available pre-thread server example, which will help me a lot to understand. Do you have any suggestion?
    7. Many thanks in advance.