Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

How to time out a thread?

Posted on 2006-10-20
7
Medium Priority
?
233 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
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!

 

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 2000 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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

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…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
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.

664 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