Solved

How to determine termination status of a thread.

Posted on 1998-10-11
11
399 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
 
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

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 …
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
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.
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …

920 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now