Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Thread Handle Query

Thread Handle Query

Scheduled Pinned Locked Moved C / C++ / MFC
tutorialquestionc++databasedata-structures
8 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Nirav Doshi
    wrote on last edited by
    #1

    Hi, I have a multi-threaded OCX (MFC) - which spawns 5 worker threads at a time, for a list of jobs. I am using WaitForMultipleObjects() with the handles of the 5 threads to wait until any of the thread finishes. As soon as WaitForMultipleObjects() returns, that thread is reused for the next job in the queue. I need to know how do I check if the handle of a given thread is valid or not! When a given thread "ends", its handle is NOT always NULL, and so cannot be checked as: if(m_pthJob[nItr]->m_hThread == NULL) Could you please guide me how to check if the handle is valid or invalid? Thanks, Nirav Doshi * Don't wish it was easier, wish you were better! *

    M D 2 Replies Last reply
    0
    • N Nirav Doshi

      Hi, I have a multi-threaded OCX (MFC) - which spawns 5 worker threads at a time, for a list of jobs. I am using WaitForMultipleObjects() with the handles of the 5 threads to wait until any of the thread finishes. As soon as WaitForMultipleObjects() returns, that thread is reused for the next job in the queue. I need to know how do I check if the handle of a given thread is valid or not! When a given thread "ends", its handle is NOT always NULL, and so cannot be checked as: if(m_pthJob[nItr]->m_hThread == NULL) Could you please guide me how to check if the handle is valid or invalid? Thanks, Nirav Doshi * Don't wish it was easier, wish you were better! *

      M Offline
      M Offline
      Michael Dunn
      wrote on last edited by
      #2

      When you create a thread, you get a handle back. That handle remains valid until you explicitly close it (or your process exits, but by that time it's too late to use the handle). The handle remains valid even after the thread exits, because the thread object in the kernel doesn't go away until all handles on it are closed. When a thread exits, your handles don't magically become null. If your handle is becoming invalid (is WaitForMultipleObjects() returning an error?) then you're doing something else wrong with the handles. --Mike-- Personal stuff:: Ericahist | Homepage Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ ---- I even hear the Windows "OMG I booted up fine" sound.   -- Paul Watson diagnosing hardware problems.

      N 1 Reply Last reply
      0
      • M Michael Dunn

        When you create a thread, you get a handle back. That handle remains valid until you explicitly close it (or your process exits, but by that time it's too late to use the handle). The handle remains valid even after the thread exits, because the thread object in the kernel doesn't go away until all handles on it are closed. When a thread exits, your handles don't magically become null. If your handle is becoming invalid (is WaitForMultipleObjects() returning an error?) then you're doing something else wrong with the handles. --Mike-- Personal stuff:: Ericahist | Homepage Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ ---- I even hear the Windows "OMG I booted up fine" sound.   -- Paul Watson diagnosing hardware problems.

        N Offline
        N Offline
        Nirav Doshi
        wrote on last edited by
        #3

        Michael Dunn wrote: If your handle is becoming invalid (is WaitForMultipleObjects() returning an error?) Yes! I'll explain here: Suppose I have 12 jobs. Since my MAX_THREADS is 5, 7 jobs are pending the first time WaitForMultipleObjects() is called. As and when my WaitForMultipleObjects() returns, I get back to assigning another job to that (returned) thread. I have another small loop just before calling WaitForMultipleObjects() where I an checking if by the time I was assigning another job to the first thread that returned, if any other thread has finished. To find if any other thread has finished working till I am assigning another job, I am checking if the thread handle is valid/invalid. Here I am getting the thread handle sometimes as NULL (0x00000000) or some junk (0xfeeeeeee, etc.) so I am unable to check for it. I have another method (which I didn't really like!), which is using a thread variable to give the current thread state. But I hope, there's some way to check if the thread handle is valid/invalid. Thanks, Nirav Doshi * Don't wish it was easier, wish you were better! *

        1 Reply Last reply
        0
        • N Nirav Doshi

          Hi, I have a multi-threaded OCX (MFC) - which spawns 5 worker threads at a time, for a list of jobs. I am using WaitForMultipleObjects() with the handles of the 5 threads to wait until any of the thread finishes. As soon as WaitForMultipleObjects() returns, that thread is reused for the next job in the queue. I need to know how do I check if the handle of a given thread is valid or not! When a given thread "ends", its handle is NOT always NULL, and so cannot be checked as: if(m_pthJob[nItr]->m_hThread == NULL) Could you please guide me how to check if the handle is valid or invalid? Thanks, Nirav Doshi * Don't wish it was easier, wish you were better! *

          D Offline
          D Offline
          Diddy
          wrote on last edited by
          #4

          How are you starting your threads? If you are using AfxBeginThread (and looking at m_pthJob[nItr]->m_hThread, it looks if you are), I suspect you are being plauged by MFC's auto deleting thread system. Make sure you set the m_bAutoDelete member of the returned thread to FALSE before starting the thread (create it in a suspeded state). The thread handle will then remaing valid, even after the thread is finished. If it is running, WaitForSingleObject(hThread, 0) will give you WAIT_OBJECT_0, if not, it will give you WAIT_TIMEOUT. Remeber to then delete your CWinThread's manually Or, use DuplicateHanlde to copy the m_hThread handle from the real WinThread to someewhere else - then clean up using CloseHandle.

          N 1 Reply Last reply
          0
          • D Diddy

            How are you starting your threads? If you are using AfxBeginThread (and looking at m_pthJob[nItr]->m_hThread, it looks if you are), I suspect you are being plauged by MFC's auto deleting thread system. Make sure you set the m_bAutoDelete member of the returned thread to FALSE before starting the thread (create it in a suspeded state). The thread handle will then remaing valid, even after the thread is finished. If it is running, WaitForSingleObject(hThread, 0) will give you WAIT_OBJECT_0, if not, it will give you WAIT_TIMEOUT. Remeber to then delete your CWinThread's manually Or, use DuplicateHanlde to copy the m_hThread handle from the real WinThread to someewhere else - then clean up using CloseHandle.

            N Offline
            N Offline
            Nirav Doshi
            wrote on last edited by
            #5

            Hello Diddy, You're right about the thread being deleted automatically since I'm not setting the AutoDelete flag to FALSE! But I was doing it expecting the thread handle to be set to NULL when the thread finished - or something which gave me a response that the thread is done working. So, how would I then get to know if a thread is not running ((hopefully) without using a variable/flag)? I need to check if a given thread is currently finished or still working. Thanks, Nirav * Don't wish it was easier, wish you were better! *

            D 1 Reply Last reply
            0
            • N Nirav Doshi

              Hello Diddy, You're right about the thread being deleted automatically since I'm not setting the AutoDelete flag to FALSE! But I was doing it expecting the thread handle to be set to NULL when the thread finished - or something which gave me a response that the thread is done working. So, how would I then get to know if a thread is not running ((hopefully) without using a variable/flag)? I need to check if a given thread is currently finished or still working. Thanks, Nirav * Don't wish it was easier, wish you were better! *

              D Offline
              D Offline
              Diddy
              wrote on last edited by
              #6

              To check if a thread is running: CWinThread* pThread = .... if(::WaitForSingleObject(pThread->m_hThread, 0) == WAIT_OBJECT_0)) { // thread is running } else { // thread has finished } The other way is also: if(::GetExitCodeThread(pThread->m_hThread, &dwExit) != 0 && dwExit == STILL_ACTIVE) { // thread is running } else { // thread has finished } But the first is usually prefered. With both, you must be careful you are working with a valid thread handle. FYI there are 2 ways (that i know of) to be sure you have a vaid handle with MFC threads: Autodelete - default --------------------- CWinThread* pThread = ::AfxBeginThread(...); This way, as you have discovered, you can't do anything with the pThread as MFC can delete it at any time. After the above thread has been started, doing pThread-> is ALWAYS a risky bit of code. You don't know when MFC will kill off your CWinThread object, and you could be refering to a bit of memory that has just been deleted. DuplicateHandle ---------------- CWinThread* pThread = ::AfxBeginThread(...CREATE_SUSPENDED); HANDLE h; ::DuplicateHandle(pThread->m_hThread, h, ...); This works because handles are refrenced counted. The DuplicateHanld call bumps this count up to 2 and puts a copy in 'h', so when CWinThread autodeletes and does a CloseHandle on it's m_hThread member, the handle isn't realy closed until you do a CloseHandle on 'h'. Don't be tempted to do this: CWinThread* pThread = ::AfxBeginThread(...CREATE_SUSPENDED); HANDLE h = pThread->m_hThread; As your count will still only be at 1. m_bAutoDelete = FALSE; ---------------------- As shown above, this is usually the easiest. Just delete your CWinThread* and that will close your thread handle.

              N 1 Reply Last reply
              0
              • D Diddy

                To check if a thread is running: CWinThread* pThread = .... if(::WaitForSingleObject(pThread->m_hThread, 0) == WAIT_OBJECT_0)) { // thread is running } else { // thread has finished } The other way is also: if(::GetExitCodeThread(pThread->m_hThread, &dwExit) != 0 && dwExit == STILL_ACTIVE) { // thread is running } else { // thread has finished } But the first is usually prefered. With both, you must be careful you are working with a valid thread handle. FYI there are 2 ways (that i know of) to be sure you have a vaid handle with MFC threads: Autodelete - default --------------------- CWinThread* pThread = ::AfxBeginThread(...); This way, as you have discovered, you can't do anything with the pThread as MFC can delete it at any time. After the above thread has been started, doing pThread-> is ALWAYS a risky bit of code. You don't know when MFC will kill off your CWinThread object, and you could be refering to a bit of memory that has just been deleted. DuplicateHandle ---------------- CWinThread* pThread = ::AfxBeginThread(...CREATE_SUSPENDED); HANDLE h; ::DuplicateHandle(pThread->m_hThread, h, ...); This works because handles are refrenced counted. The DuplicateHanld call bumps this count up to 2 and puts a copy in 'h', so when CWinThread autodeletes and does a CloseHandle on it's m_hThread member, the handle isn't realy closed until you do a CloseHandle on 'h'. Don't be tempted to do this: CWinThread* pThread = ::AfxBeginThread(...CREATE_SUSPENDED); HANDLE h = pThread->m_hThread; As your count will still only be at 1. m_bAutoDelete = FALSE; ---------------------- As shown above, this is usually the easiest. Just delete your CWinThread* and that will close your thread handle.

                N Offline
                N Offline
                Nirav Doshi
                wrote on last edited by
                #7

                Thank you very much Diddy for taking the efforts to explain this! :rose::-O I've taken note about your DuplicateHandle() point! Thanks! I'm now changing a majority of my processor code & logic. I guess, using a variable which gives me the current state of each of my threads is the best work-around for my problem. :doh: Working on it...:~ Thanks again to you and Micheal for your replies.:cool: Hope I could be able to help you both here someday! - Nirav Doshi * Don't wish it was easier, wish you were better! *

                D 1 Reply Last reply
                0
                • N Nirav Doshi

                  Thank you very much Diddy for taking the efforts to explain this! :rose::-O I've taken note about your DuplicateHandle() point! Thanks! I'm now changing a majority of my processor code & logic. I guess, using a variable which gives me the current state of each of my threads is the best work-around for my problem. :doh: Working on it...:~ Thanks again to you and Micheal for your replies.:cool: Hope I could be able to help you both here someday! - Nirav Doshi * Don't wish it was easier, wish you were better! *

                  D Offline
                  D Offline
                  Diddy
                  wrote on last edited by
                  #8

                  No problem :)

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups