Solved

How to time out a thread?

Posted on 2006-10-20
7
230 Views
Last Modified: 2010-04-01
Hi,

In my test application, I have 1 thread running and it hang in some 3rd party library code, how can I force he thread to exit in the main application?
0
Comment
Question by:4eyesgirl
[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
  • 4
  • 3
7 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 17774940
The 'brute' way would be to 'TerminateThread(hThread,-1);', however that gives the thread no chance to clean up properly, e.g. like

LONG WINAPI ThreadProc ( LPVOID pv)
{

HANDLE hStopEvent = (HANDLE) pv;

  for ( ;;)
  {
    DWORD dwRes = WaitForSingleObject ( hStopEvent, 10);

    if ( WAIT_TIMEOUT != dwRes) ExitThread ( 0);

    // ...
  }

  return 0;
}

as an outline. Some more complete sample code would be

HANDLE ConnectEvent ( LPCTSTR pszName)
{

   HANDLE hEvent   =   CreateEvent (   NULL,
                                       FALSE,
                                       FALSE,
                                       pszName
                                   );

   if  (   INVALID_HANDLE_VALUE    ==  hEvent)
       {
           if  (   ERROR_ALREADY_EXISTS    ==  GetLastError    ())
               {
                   hEvent  =   OpenEvent   (   SYNCHRONIZE,
                                               FALSE,
                                               pszName
                                           );

                   if  (   INVALID_HANDLE_VALUE    ==  hEvent)
                       {

                           return NULL;
                       }
               }
       }

   return hEvent;
}

HANDLE hEvent = ConnectEvent(NULL);
DWORD dwTID;
HANDLE hThread = CreateThread(NULL,0,MyThread,(LPVOID) hTermEvent,0,&dwTID);

Sleep (100000);

SetEvent(hTermEvent); // signal termination request

LONG WINAPI MyThread(LPVOID pv)
{
    HANDLE hTermEvent = (LPVOID) pv;

    for (;;)
    {

        DWORD dwResult = WaitForSingleObject(hTermEvent, 1):

        if (WAIT_TIMEOUT != hTermEvent) return -1; // event was set


        // functionality goes here....
    }

    return 0;
}
0
 

Author Comment

by:4eyesgirl
ID: 17775057
Hi jkr,

I am completely new to the threading worlds, so I may need some more clearly picture for the time being.

This is the same question I ask from the other day.  Basically, one of my thread is hanging in
myFunc(),  What is the simpliest way to check from the main() - let say every 2 min to ask user wish to kill?  This question is urgent and if I can get some quick answer, I will take it.

I am not sure I can use "if ( WAIT_TIMEOUT != dwRes) ExitThread ( 0);" or may be use it when I ask user to quick every 2 minutes and if the user say yes?  Can you show me how to do that?




int main()
{
   int threadCount=10; // default to 10 threads
   int Count=100;
 for (int i = 0; i < threadCount; i++)
      {
         //myFunc(choice);
         DWORD dwThreadId, dwThrdParam = 1;
         
         hInputThread[i] = CreateThread(
         NULL,                        // no security attributes
         0,                           // use default stack size  
         myFunc,                      // thread function
         &Count,            // argument to thread function
         0,                           // use default creation flags
         &dwThreadId);                // returns the thread identifier
 

         cout << "Created thread id " <<  dwThreadId << " Successfully" << endl;
         threadId[i] = dwThreadId;
         if (hInputThread == NULL)
         {  
            printf("thread creation failed");
         }
         /*else
         {
            CloseHandle( hInputThread );
         }*/

      }


      bool terminated[MAX_THREADS] = { false };

      while( threadAlive > 0)
      {
         if (!terminated[k])
         {
               DWORD dret;
               if ((dret = WaitForSingleObject(hInputThread[k], 500)) == WAIT_OBJECT_0)
               {                  
                  terminated[k] = true;
                  threadAlive--;  
                  cout << "\nExit thread id " << threadId[k] << " Successfully" << endl;
               }
               else if (dret != WAIT_TIMEOUT)
               {
                  cout << "\nerror WaitForSingleObject = " << GetLastError() << endl;
                  break;
               }
               else cout << "*";  
         }
         Sleep(200);
         k = (k +1) %threadCount;  // runs from 0 to threadCount
      }
 
      return 0;
 
}
0
 
LVL 86

Expert Comment

by:jkr
ID: 17775134
>>Basically, one of my thread is hanging in myFunc()

Ah, I see, that is different. In this case, you would need to have some kind of a watchdog/hearbeat mechanism that checks whether the thread is still responding, which would basically work right the other way round like

HANDLE ConnectEvent ( LPCTSTR pszName)
{

   HANDLE hEvent   =   CreateEvent (   NULL,
                                       FALSE,
                                       FALSE,
                                       pszName
                                   );

   if  (   INVALID_HANDLE_VALUE    ==  hEvent)
       {
           if  (   ERROR_ALREADY_EXISTS    ==  GetLastError    ())
               {
                   hEvent  =   OpenEvent   (   SYNCHRONIZE,
                                               FALSE,
                                               pszName
                                           );

                   if  (   INVALID_HANDLE_VALUE    ==  hEvent)
                       {

                           return NULL;
                       }
               }
       }

   return hEvent;
}

HANDLE hHeartbeatEvent = ConnectEvent(NULL);
DWORD dwTID;
HANDLE hThread = CreateThread(NULL,0,MyThread,(LPVOID) hHeartbeatEvent,0,&dwTID);

ULONG ulTimeoutCount = 0;

for (;;) {

    Sleep(1000);

    DWORD dwResult = WaitForSingleObject(hHeartbeatEvent, 1):

    if (WAIT_TIMEOUT == hTermEvent) ulTimeoutCount++; // event was *NOT* set

    if (ulTimeoutCount > MAX_TIMEOUT_COUNT) {
   
        TerminateThread(hThread,0); // kill thread...

        break; // ...exit loop
}


LONG WINAPI MyThread(LPVOID pv)
{
    HANDLE hHeartbeatEvent = (LPVOID) pv;

    for (;;)
    {
        SetEvent(hHeartbeatEvent);

        // functionality goes here....
    }
}
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:4eyesgirl
ID: 17775326
jkr -
Sorry I don't understand the code above...Dummy me...

Am I suppose to create another thread call MyThread?  Or am I suppose to create a heartbeatEvent that associate with each thread I am running?

Kind of confused.  Please forgive my ignorance, I really don't have any threading background.
0
 
LVL 86

Expert Comment

by:jkr
ID: 17775360
>>Am I suppose to create another thread call MyThread?

No, just have the thread set an event periodically to see if it is still alive (or 'not hanging'). The main app will check that also periodically and after a max. number of timeouts, will assume 'hanging' and forcibly shutdown the thread.

>>Or am I suppose to create a heartbeatEvent that associate with each thread I am running?

That depends on your setup. If you need to check a 'hanging' condition for ach thread that is running, you need a a separate hearbeat event for each.

>>Please forgive my ignorance, I really don't have any threading background.

No problem ;o) - check out http://msdn.microsoft.com/library/en-us/dndllpro/html/msdn_threads.asp ("Multithreading for Rookies")
0
 

Author Comment

by:4eyesgirl
ID: 17775498
jkr - what is MAX_TIMEOUT_COUNT?

I want to ask the user to quit after every 2 minutes, how can I do that?

What is the number in ULONG ulTimeoutCount equivalent to 2 minutes?
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 17775771
>>what is MAX_TIMEOUT_COUNT?
>>I want to ask the user to quit after every 2 minutes, how can I do that?

In the above example, the hearbeat event is checked every second (see the 'Sleep()' call), so if you want to be sure that the thread is terminated after 2mins, I'd up the interval to 10s and make that

#define MAX_TIMEOUT_COUNT (2 * 60 / 10)

for (;;) {

    Sleep(1000);

    DWORD dwResult = WaitForSingleObject(hHeartbeatEvent, 1):

    if (WAIT_TIMEOUT == hTermEvent) ulTimeoutCount++; // event was *NOT* set
      else ulTimeoutCount = 0; // reset count - forgot that...

    if (ulTimeoutCount > MAX_TIMEOUT_COUNT) {
   
        TerminateThread(hThread,0); // kill thread...

        break; // ...exit loop
}
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

635 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