[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 227
  • Last Modified:

Thread termiation results in an exception

Hi folks,

Everytime I try to terminate a thread, I get an exception, and I can't shutdown my hardware correctly. Even without the hardware lines, the thread just doesn't termnate without an error. I launch the thread by pressing a button on my GUI; I expect to terminate it by toggling the same button again. It never hits the break point message box below that says uninitializing. Launching occurs fine. What is my mistake?

void MVMFrm::WxToggleButton3Click(wxCommandEvent& event)
    {
        Flash5 = !Flash5;
        if (Flash5)
        {
        if ( m_pOpenCVThread->Create() != wxTHREAD_NO_ERROR )
             {
             MessageBox(NULL,"Thread Error!","Error",MB_OK);

                   wxExit( );
             }

          // start the thread
          if ( m_pOpenCVThread->Run() != wxTHREAD_NO_ERROR )
             {


                wxExit( );
             }

        }
    else    //delete thread
        {
        BUFUSB_StopCameraEngine();
        BUFUSB_UnInitDevice();
        MessageBox(NULL,"Uninitializing!","Error",MB_OK);
        m_pOpenCVThread->Delete( );


    }
0
Wanderinglazyeye
Asked:
Wanderinglazyeye
  • 4
  • 3
  • 3
  • +1
5 Solutions
 
jkrCommented:
The order of calls when stopping the thread seems a bit off - does

    else    //delete thread
        {
        MessageBox(NULL,"Uninitializing!","Error",MB_OK);
        m_pOpenCVThread->Delete( );
        BUFUSB_StopCameraEngine();
        BUFUSB_UnInitDevice();

    }

work? Note that the thread might still use resources that are cleaned up by stopping the camera while it is stlll running. Alternatively, you could try

    else    //delete thread
        {
        m_pOpenCVThread->Pause( );
        BUFUSB_StopCameraEngine();
        BUFUSB_UnInitDevice();
        MessageBox(NULL,"Uninitializing!","Error",MB_OK);
        m_pOpenCVThread->Delete( );
    }

but ordering the calls differently seems cleaner to me.
0
 
itsmeandnobodyelseCommented:
>>>> Everytime I try to terminate a thread

Terminating a thread by 'TreminateThread' is only a last resort. Better send the thread a message (if using CWinThread) that it should stop by itself or set a global (or a static class member) bool flag which periodically needs to be checked by all threads or use a stop event where all threads are waiting for (with short timeouts or while they are waiting on other events by calling WaitForMultipleObejcts with the 'or' argument).

Regards, Alex
0
 
Infinity08Commented:
Does it enter the else statement ? Is it blocked on one of the two lines before the MessageBox ?
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!

 
WanderinglazyeyeAuthor Commented:
JKR - changing the sequence as you described didn't fix the problem, but narrowed it.

Infinity08 - it does enter the else statement. It seems it gets hung on the command to the camera. Yet, this is perfectly legal given the development guide that came with it.

Itsmeandnobodyelse - can you clarify the approach?

Thanks

WLE
0
 
WanderinglazyeyeAuthor Commented:
BTW folks, I am sorry about the indentations. I am using wxDevC++ (not Visual Studio) and it doesn't seem to do a good job in this regard.
0
 
jkrCommented:
>>but narrowed it.

In which way? ;o)

>>I am sorry about the indentations

Never mind, EE kills almost all indentations.
0
 
WanderinglazyeyeAuthor Commented:
Narrowed it, meaning eliminated the order of thread termination as a possible culprit. Sorry about the confusion.
0
 
Infinity08Commented:
>> Infinity08 - it does enter the else statement. It seems it gets hung on the command to the camera. Yet, this is perfectly legal given the development guide that came with it.

So, if you comment that line, the thread terminates correctly ?

Do you by any chance have another thread still using the camera ?
0
 
WanderinglazyeyeAuthor Commented:
Yes, commenting out that line makes it terminate correctly.
0
 
Infinity08Commented:
I don't know the BUFUSB_StopCameraEngine and BUFUSB_UnInitDevice API's, but I imagine that they're trying to shut down a USB connection with the camera, correct ?

I assume you already checked that that's the correct way to do that ? And that no other thread/process is still using the camera at that moment ?

Did you also make sure that the initialization was done in the same thread ? In other words, do the BUFUSB_StopCameraEngine and BUFUSB_UnInitDevice calls have unique access to the camera, and the code connected to it ?
0
 
itsmeandnobodyelseCommented:
>>>> I am using wxDevC++ (not Visual Studio)
if you have a Visual Studio available you could it it use for indentation purpose only.

>>>> Itsmeandnobodyelse - can you clarify the approach?
How did you 'terminate' the threads? If calling TerminateThread you are 'killing' the thread and it is not freeing any resources, handles, ...

So, my approach is to have each thread terminate itself rather than forcing it to be terminated by the main thread. To make that working each thread must check in very short periods whether it should go on or have to exit. If a thread is 'waiting' for an event somewhere it additionally needs to wait for THE stop event signaled by the main thread. So a typical thread code would be like

void threadFunc(void* p)
{
      ThreadData* pt = (ThreadData*) p;

       while (!pt->stopflag &&                // check thread stop flag at each iteration
                  !ThreadData::stopallflag)  // check general stop flag which is a static member
       {
             ....
             dosomething(pt->stopflag, ....);  // pass stopflag(s) to any length function

             ...
             HANDLE h[2] = {  pt->stopeventhandle, ThreadData::allstopeventhandle };
             ret = WaitForMultipleObjects(h, 2, FALSE, ...);   // FALSE means wait for either handle to get signaled
             switch (ret)
             {
              ...
              case WAIT_OBJECT_1: return;   // stop event was signaled
             }
             ...
       }
}

The main thread would do in case of termination:

   ThreadData::allstopflag = true;
   SetEvent(ThreadData::allstopeventhandle);
   for (int i = 0; i < MAX_THREAD; ++i)
    {
           threaddata[i]->stopflag = true;
    }
    Sleep(2000);   // wait some time until all threads have recognized

Note, you could call TerminateThread after that Sleep for threads that didn't recognize (though actually you should get them all closed somehow). You would need to implement some kind of 'feedback', e. g. in ThreadData struct, a thread can give when recognized termination.

Regards, Alex



0
 
itsmeandnobodyelseCommented:
Note, I don't know the Wx classes. So, it could be that

     m_pOpenCVThread->Delete( );

does somewhat similar as I described (e. g. was sending a stop message to the thread to delete). If so, you have to add maybe two things: for the threads you have to avoid any blocking call which was not checking for the stop message. Check your docs whether the blocking (waiting) calls do that or not. For the main thread you may have to wait some time at end before exiting in orderto give all threads time to smoothfully end. Try it with a Sleep and decrease sleep times until one thread was hanging. Then double the last time and you should be save.
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

  • 4
  • 3
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now