?
Solved

How to determine termination status of a thread.

Posted on 1998-10-11
11
Medium Priority
?
405 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 280 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
In this post we will learn different types of Android Layout and some basics of an Android App.
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.
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Suggested Courses

752 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