Solved

How to time out a thread?

Posted on 2006-10-20
7
223 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
  • 4
  • 3
7 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
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
Comment Utility
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
Comment Utility
>>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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:4eyesgirl
Comment Utility
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
Comment Utility
>>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
Comment Utility
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
Comment Utility
>>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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

762 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

12 Experts available now in Live!

Get 1:1 Help Now