No announcement yet.

Thread interrupt

  • Filter
  • Time
  • Show
Clear All
new posts

  • Thread interrupt


    I'm rewriting and optimizing my code (to work in multi-user environment) and ran into a problem:
    How do I interrupt a thread?

    I have two threads with basically a different method of getting the same result. So if one thread finishes and does have a proper result, I do not want to wait for the other one.
    I used to have a Global for this which worked as a signal for the thread to goto to the ending (that is: close SQL statement, close SQL thread ; which HAVE to do done in the thread itself!).
    I can use the same approach (a global) but now with the use of critical section but this will not enhance my throughput (which is what I'm trying to optimize!).

    Is there a good way of doing this? I have been reading about Events that can be set using the handle of the thread, but this looks a bit difficult (for instance: how do you ensure it's signaled by the right thread). I can't find proper code on the forum so I'm hoping for something easier.

    Hope someone can help a little




  • #2
    I haven't had a need for this but you should be able to do a Thread Status (??)


    mailto:[email protected][email protected]</A>
    Scott Turchin
    True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi


    • #3
      Scott, thanks for your swift response.

      I can surely read the Thread Status, but then what?
      This is where I'm getting stuck. I noticed that the thread likes it best if the SQL Statements that are used specifically for a thread, are closed in that thread.
      More severe: SQL_Thread has a unique number in each thread and must be started and closed inside the thread.

      That's what I'm looking for : how do I tell the thread to do something? Just the change of a variable that was send would be ok (as I used to do with globals), so I can use it as a trigger to have the thread finish itself immediately.




      • #4
        When you create a thread, you pass it an arbitrary DWORD value that can
        be used in any way you like. For your purposes, perhaps it would be good
        to pass a pointer to a variable or memory block created in the main
        program. (Each thread would need its own variable or memory block to
        avoid conflicts). The thread could then watch the variable to see if the
        main program has changed it, and react accordingly.

        Or, if your thread has a message loop, you might have your program send
        it a custom message.

        Tom Hanlin
        PowerBASIC Staff


        • #5
          Have you thought of using an array for your thread handles then using WaitForMultipleObjects()
          with the wait flag set to false causing it to return when either of the threads complete. You determine which thread from the result code.



          • #6
            I think that that is what I'm doing (my testing was wrong, sorry: it was working after all).

            I use a pointer to a UDT that I pass to the two threads like this : Thread Create MyThread (MyPtr) to hThread(0). I used CoTaskMemAlloc to get the pointer so I can use the pointer in the thread to get the handle to the memory (neat trick!).
            I assigned 2 members for the results, so I just wait for a change in value.

            DO WHILE MyPTR.ThreadResult1 = 0 AND MyPTR.ThreadResult2 = 0
                SLEEP 1
            If one thread provides a result, its value changes. I then provide a counter value to the other one: -1
            So in each thread, there a lot of :
            IF @MyPtr.ThreadResult1 = -1 THEN ' or .ThreadResult2 in MyThread2
                GOTO ENDING
                EXIT FUNCTION
            END IF
            In Ending, I close the SQL Statement and the SQL_Thread and set the value to 2 (i.e. no result) if it is -1

            So in my wrapper I then wait for them both to end and close them.
            This seems similar to what you're suggesting (correct me if I'm wrong).

            I tested your idea (never worked with WaitForMultipleObjects so ...).
            I does provide a return as soon as one of the threads is finished.
            But how does it tell the other thread to finish? Forgive me if I'm not understanding you correctly (I'm kinda new to threading), but the other thread just continues.
            How could I do that without the 'flags' as used above? If it possible in any faster way, I'm very interested.

            BTW: if I use
                result& = WaitForMultipleObjects(1, hThread(1), %FALSE, %INFINITE)
                msgbox "(0) = " + Str$( hThread(0) ) + " ; (1) = " + Str$( hThread(1) )
            the messagebox provide (0) = 432 ; (1) = 484.

            What can I do with these values? How do I know which thread is actually finished (if I don't use the 'flags' as above)?




            [This message has been edited by jeroen brouwers (edited February 13, 2001).]


            • #7
              Jeroen, what is the value of result&?

              I believe you will see that result& from your example is either 0 or 1
              if one of your thread handles has been signaled. If your array is option
              base 1, increment the value of result& to determine the array element/thread
              which has completed first.

              I think you will need a flag to indicate to the thread which is still running
              it is time to stop processing and exit. Are you running this on a multi-processor system?
              Does the same functions/thread always complete first? If running on a single processor machine,
              two competing (parallel) threads are going to detract from the overall performance. Has your timing
              indicated this?

              Have fun and success,



              • #8
                Thanks. Of course it should be the result& value! Although I don't really understand the 'increment the value of result' idea.
                I test on both single and multi processor systems and the thread that finishes first depends on the application input. Even when I know (from the flag vars) which one is finished the value of hThread(0) en (1) are always equal and the result& seems 0 all the time!
                How does this work exactly?

                Hope you can explain a little more.




                • #9
                  Jeroen, WaitForMultipleObjects() will return the ZERO based
                  array element which finished first (if it is waiting for the
                  first event/thread to complete like it is in your application).
                  This means if a zero is returned, your first thread finished first
                  and if a one is returned, your second thread finished.

                  So, given that your array starts at index 1, you would add 1 to the value
                  of result& to determine which of your threads has completed first.

                  You said result& is always zero. That means your first thread (hThread(1))
                  is apparently finishing first.

                  Your code snippet:
                  result& = WaitForMultipleObjects(1, hThread(1), %FALSE, %INFINITE)
                  msgbox "(0) = " + Str$( hThread(0) ) + " ; (1) = " + Str$( hThread(1))

                  ...has a flaw if it is for your two threads.

                  Your first parameter is a "1". That means you only have one element in your array or
                  no array at all. It should be a 2 for a two element array.

                  If your array is Dim'd as: Dim hThread(1 to 2) as global long...
                  When WFMO returns the value of result& will be 0 or 1 if one of the threads completed.
                  It will not return the handle of the thread which completed, it returns the ZERO based array
                  index of the handle which completed first.


                  • #10
                    Thanks Ron,
                    Very clear. Except for the Global Long: I use a local now because of my multi-user environment (the threading we're taking about is within the DLL and starts two pieces of code as inner-threads).
                    Does that make a difference?

                    BTW, if you can spare a little time: I want to have a boss - worker model at the entry of my dll. I believe that's the name for this principle: the boss is the function that takes all incoming requests (i.e. threads) and sets a worker thread to action.
                    I've read about it, but its not really clear. What are the main principles / where can I find more info (saw your example on the forum that looked like but ... ehhh.. )