Solved

How to determine termination status of a thread.

Posted on 1998-10-11
11
400 Views
Last Modified: 2013-11-20
Hi

I will probably figure this out during the time period it takes someone to respond, but this weird.

So here is the setup.  I have an array of CWinThread objects.  Some of these are NULL, indicating they are not currently in use.  Others are assigned a thread that is running, but the thread will probably terminate after about, ohhhhh, 10 seconds.

To prevent the program from exiting while a thread is running, I am using this:

  int i;
  DWORD exitcode;

  for (int j = 0; j < 100; j++)
  { for (i = 0; i < 16; i++)
    { if (m_Threads[i] != NULL)
      { GetExitCodeThread (m_Threads[i]->m_hThread, &exitcode);

        if (exitcode == STILL_ACTIVE)
        { break; }
        MessageBeep (0xffffffff);
      }
    }

    if (exitcode != STILL_ACTIVE)
    { break; }

    Sleep (100); // Wait until all threads have terminated.
  }

The intent of the code is to wait until the program has exited, but the loops will never terminate early, they always go through the whole thing.

What could be causing this?
0
Comment
Question by:helpmealot
  • 5
  • 3
  • 3
11 Comments
 
LVL 23

Expert Comment

by:chensu
ID: 1323185
You should use the Wait functions (e.g. WaitForSingleObject) on the thread handles to detect if the threads has terminated. Your method wastes a lot of CPU time. As a result, the threads have less time to execute.
0
 
LVL 86

Accepted Solution

by:
jkr earned 70 total points
ID: 1323186
'GetExitCodeThread()' is not very reliable for this task - i prefer calling 'WaitForSingleObject()' using a small timeout - the object's state is signaled when it terminates, so 'WAIT_TIMEOUT' guarantees that it's still running...

0
 

Author Comment

by:helpmealot
ID: 1323187
Okay, it sounds like this function WaitForSingleObject is what I am looking for.  However, I am not sure how to use it.  This is my first project using threads, so I am very unclear as to what I do with it.  Can you please elaborate?  I will divide the points between you if you both give good explanations :)
0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 
LVL 23

Expert Comment

by:chensu
ID: 1323188
A thread object's state is signaled when the thread terminates.

if (::WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0)
{
    // the thread has terminated
}

The WaitForSingleObject function returns when one of the following occurs:

1. The specified object is in the signaled state.
2. The time-out interval elapses.
0
 
LVL 86

Expert Comment

by:jkr
ID: 1323189
Well, IMHO there's nothing to add to chensu's explanation, the only difference is that i'd use

if (::WaitForSingleObject(hThread, 1) == WAIT_TIMEOUT)
{
    // the thread is still running...
}

0
 

Author Comment

by:helpmealot
ID: 1323190
Okay I see, that seems to make sense now.  I am going to split the points between you because I was able to incorporate chensu's suggestion for the exiting part of the program and jkr's solution for the parts of the program where a new thread would start.  First though, I have one other question (coming):
0
 

Author Comment

by:helpmealot
ID: 1323191
You see, to keep track of the threads running in the program, I have created an array of CWinThreads.  When a new thread is created, this code is executed:

  { CWinThread *nThread;
    // ...
    // nthread is assigned a valid CWinThread object.

    for (int i = 0; i < 16; i++) // 16 cause I have 16 CWinThreads in the array.
    { if (m_Threads[i] != NULL)  // All CWinThreads are initialized to 0 when the program starts.
      { if (::WaitForSingleObject (m_Threads[i], 1) != WAIT_TIMEOUT) // thread is dead.
        { m_Threads[i] = nThread;
          break;
        }
      }
      else // or object hasn't been used yet.
      { m_Threads[i] = nThread;
        break;
      }
    }
  }

Is that code good?  Are there any problems with it?  Any potential improvements?  That sort of thing.

One more other question along these same lines coming:
0
 

Author Comment

by:helpmealot
ID: 1323192
When my program exits, I want it to wait for all threads to terminate.  Is this right:

  for (i = 0; i < 16; i++)
  { if (m_Threads[i] != NULL)
    { ::WaitForSingleObject (m_Threads[i]->m_hThread, INFINITE); }
  }

It seems to work, but I have had experience where something seems to work but it turns out it doesn't.  That is why I am asking :-)

Does that make sense?  Any other suggestions?

I will give each of you 75 points and an A since you have both helped me a great deal!

Thanks!
0
 
LVL 23

Expert Comment

by:chensu
ID: 1323193
1. Regarding the code when a new thread is created, I think you can use
if (::WaitForSingleObject(m_Threads[i]->m_hThread, 0) == WAIT_OBJECT_0)
instead of
if (::WaitForSingleObject(m_Threads[i]->m_hThread, 1) != WAIT_TIMEOUT)

2. Regarding the code when the program exits, I think you may use a certain time instead of INFINITE in case there is something wrong. MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx are your options too.

In addition, it is more reliable to handle the errors returned by WaitForSingleObject.
0
 
LVL 86

Expert Comment

by:jkr
ID: 1323194
If you already have an array of thread handles (e.g. you know the number) 'WaitForMultipleObjects()' will do the job well (and is more reliable & flexible than using a loop). 'MsgWaitForMultipleObjects()' also handles messages, but if you don't need to take care about messages, it provides no advantage...
0
 

Author Comment

by:helpmealot
ID: 1323195
Okay, that has cleared up everything for me.  chensu - I am going to post a question the MFC area "addressed" to you so you can get your 75 points too.
0

Featured Post

U.S. Department of Agriculture and Acronis Access

With the new era of mobile computing, smartphones and tablets, wireless communications and cloud services, the USDA sought to take advantage of a mobilized workforce and the blurring lines between personal and corporate computing resources.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
bobThere java chalenge 45 92
CRON statement to run every 3 minutes except on Monday morning 12am to 2am 7 96
sameEnds challenge 3 167
Problem to App 4 83
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

825 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question