How to kill a MFC Thread? - c++

I spawn a thread using AfxBeginThread which is just an infinite while loop:
UINT CMyClass::ThreadProc( LPVOID param )
{
while (TRUE)
{
// do stuff
}
return 1;
}
How do I kill off this thread in my class destructor?
I think something like
UINT CMyClass::ThreadProc( LPVOID param )
{
while (m_bKillThread)
{
// do stuff
}
return 1;
}
and then set m_bKillThread to FALSE in the destructor. But I still need to wait in the destructor until the thread is dead.

Actively killing the thread:
Use the return value of AfxBeginThread (CWinThread*) to get the thread handle (m_hThread) then pass that handle to the TerminateThread Win32 API. This is not a safe way to terminate threads though, so please read on.
Waiting for the thread to finish:
Use the return value of AfxBeginThread (CWinThread*) to get the member m_hThread, then use WaitForSingleObject(p->m_hThread, INFINITE); If this function returns WAIT_OBJECT_0, then the thread is finished. Instead of INFINITE you could also put the number of milliseconds to wait before a timeout happens. In this case WAIT_TIMEOUT will be returned.
Signaling to your thread that it should end:
Before doing the WaitForSingleObject just set some kind of flag that the thread should exit. Then in your main loop of the thread you would check for that bool value and break the infinite loop. In your destructor you would set this flag then do a WaitForSingleObject.
Even better ways:
If you need even more control you can use something like boost conditions.

BTW, About TerminateThread(), use it this way.
DWORD exit_code= NULL;
if (thread != NULL)
{
GetExitCodeThread(thread->m_hThread, &exit_code);
if(exit_code == STILL_ACTIVE)
{
::TerminateThread(thread->m_hThread, 0);
CloseHandle(thread->m_hThread);
}
thread->m_hThread = NULL;
thread = NULL;
}

First you have to start the thread in a way so MFC doesn't delete the thread object when it's finished, the default setting for MFC thread is to delete itself so you want to turn that off.
m_thread = AfxBeginThread(ThreadProc, this, THREAD_PRIORITY_NORMAL ,CREATE_SUSPENDED);
m_thread->m_bAutoDelete = FALSE;
m_thread->ResumeThread();
Now in the thread, you want a mechanism that the caller thread can send it a signal to end itself. There are multiple ways, one is the WaitForSingleObject to check the status of the signal or another way is to simply send this thread a message to end itself. This is graceful ending rather killing it.
While this thread is ending itself (= exiting the thread function, cleaning up), you can have the main thread wait on it to finish before it exits.
int wait = 2000 // seconds ( I am waiting for 2 seconds for worker to finish)
int dwRes = WaitForSingleObject( m_thread->m_hThread, wait);
switch (dwRes)
{
case WAIT_OBJECT_0:
TRACE( _T("worker thread just finished") ); break;
case WAIT_TIMEOUT:
TRACE( _T("timed out, worker thread is still busy") ); break;
}
Note setting m_bAutoDelete = FALSE above made it possible we still have a valid handle when thread finishes so we can wait on it. The last thing you want to do now is delete the CWinThread object to free its memory (since we took the responsibility to do that).

You must wait, until thread do all stuff.
if(WaitForSingleObject(thread_handle, INFINITE) == WAIT_OBJECT_0)
;//all right
else
;//report error
beware using TerminateThread function, this is very dangerous.

Related

Choice between thread: time expired and user input

I'm writing a simple function that, when called, allows to execute 2 different actions (exclusive).
So there are two threads. User_choice waits until the user inserts an input and the Time_choice waits until time expires.
The choice_done shared var says that, if true, one thread has already started and blocking (it doesn't do anything!) the other one; Whereas thread_done says, if true, that thread (it doesn't matter which) has already finished, so func() waits until one thread finishes.
Here is the code.
The func procedure will be called more times during the program execution.
The various user_choice thread will be waiting forever on getline! Is it a problem? What if, after four times the program will call func() and the user doesn't insert anything, the 5th time the user inserts "yes"?
Will every user_choice thread continue the execution?? How can I kill the waiting thread? Are there other solutions?
How can I wait inside func() that a thread sets thread_done to true?
bool choice_done = false;
bool thread_done = false;
void func(){
boost::thread t1(boost::bind( time_choice() ));
boost::thread t2(boost::bind( user_choice() ));
//whait untile thread_done == true
do something...
}
// Time choice thread
void time_choice(){
sleep(5);
if(choice_done == false){
printf("Automatic choice\n");
choice_done == true;
do something...
thread_done = true;
}
}
// User choice thread
void user_choice(){
printf("Start emergency procedure?\n");
string tmp;
getline(cin, tmp);
if((tmp.compare("yes") == 0) && (choice_done == false)){
printf("Manual choice\n");
choice_done == true;
do something...
thread_done = true;
}
}
Having to create a thread for a timer is generally a sign of sub-optimal design. It does not scale well (imagine thousands of timers) and the code gets multi-threaded and more complex for no good reason. Also, sleep is not thread-safe on Linux.
Just use one thread with select and a timeout. select will wait on STDIN_FILENO for user input and timeout simultaneously.
Or, better, use a 3rd-party event-demultiplexing library, like libevent or boost::asio.

Timing inconsistency with killing thread using event

I have a multithreaded C++ Windows application. The worker thread is an infinite loop waiting for events to process, one of which is a kill thread event from main thread. The problem is that sometimes it takes a really long time (think seconds) for the worker thread to receive the kill event and terminate. Other times it's very quick (milliseconds).
// Main thread code
void deactivate()
{
while (isWorkerThreadRunning)
{
// Problem: sometimes it spends a long time in this loop
logDebug("deactivate: killing worker thread");
SetEvent(killWorker);
Sleep(20);
}
}
// Worker thread code
DWORD WINAPI WorkerThreadProc(LPVOID arglist)
{
isWorkerThreadRunning = true;
logDebug("Worker thread started");
for (bool done = false; done != true; )
{
HANDLE handles[3] = { killWorker, action1, action2 };
DWORD rc = WaitForMultipleObjects(3, handles, FALSE, INFINITE);
switch (rc)
{
case WAIT_OBJECT_0 + 0: done = true; break;
case WAIT_OBJECT_0 + 1: doAction1(); break;
case WAIT_OBJECT_0 + 2: doAction2(); break;
default: logWarn("Unhandled wait signal");
}
}
isWorkerThreadRunning = false;
logDebug("Worker thread killed");
return 0;
}
I believe that if the worker thread receives a kill event while it is busy inside doAction1() or doAction2() the kill event won't be received and processed until doAction1() or doAction2() is completed and returned. And if doAction1() or doAction2() takes a long time to return then the worker thread will take a long time to exit.
However, I have log points sprinkled throughout doAction1() and doAction2() but I don't see any of those log points in the log file. All I see are:
deactivate: killing worker thread
deactivate: killing worker thread
deactivate: killing worker thread
deactivate: killing worker thread
//....many more times
Worker thead killed
which means the worker thread is not doing any work but rather waiting inside the WaitForMultipleObjects() call.
The question is why is the WaitForMultipleObjects() call sometimes take a long time (and sometimes very quick) to signal the waiter of an event??
Would changing the timeout from INFINITE to some reasonable number fix this problem?
Thanks,
Your declaration of isWorkerThreadRunning should be volatile if it is not. You can get some strange behavior when the compiler optimizes the code if it is not volatile.
volatile bool isWorkerThreadRunning;
I would also suggest entry and exit messages in your doAction functions. That will make it clearer if you're still inside one of those functions when the exit signal is sent.

how can i spawn a process that lives only for given duration

I have a parent process and I'd like to spawn the child process for a certain duration ( say N milli seconds). I'm doing this in c++ (and windows).
Can I provide some parameter to CreateProcess that would kill it after a while and return control to the parent application ? If not, is there any other way to do this ?
Can I provide some parameter to CreateProcess...?
Yes, you may pass the desired duration (N) with the parameter lpCommandLine to the process to be started.
The child process may parse lpCommandLine and set up a timer with the desired
duration. This timer could for example be a Waitable Timer or simply a thread with
Sleep(duration); // waits the duration
ExitProcess(GetLastError()); // exits the "remote" process
The thread (a thread inside the the child process) terminates the entire child process after duration. The WaitableTimer idea would need a frequent call to a wait function. See Using Waitable Timer Objects for details.
But: The parent process will remain "in control" all the time.
However: You may additionally
enter a wait state in the parent process, using a wait function (e.g. WaitForSingleObject, waiting on the child processes handle to actually hibernate the parent process until the child process terminates. On top you may evaluate the return value of the child process by a call to the GetExitCodeProcess function.
The described schemes ensures that the desired duration is best performed, however, you may also control the duration from the parent process by means of a named event. See Using Event Objects for details. In such an approach, the parent process may set an event when the duration "is consumed". The child process waits for that event and terminates when the event was set. This approach may be a little less accurate since the parent doesn't quite know when the childs duration started.
Example with waitable timer:
Parent process:
...
#define CHILD_DURATION 2000 // 2000 ms
HANDLE hProcess;
char ChildName[MAX_PATH];
char CommandLine[MAX_PATH];
sprintf_s(ChildName,MAX_PATH,"MyChild.exe");
sprintf_s(CommandLine,MAX_PATH,"%d",CHILD_DURATION);
// start the child
hProcess = CreateProcess(ChildProcessName,CommandLine,....
if (0 == hProcess)
{
// error with process creation
printf("CreateProcessfailed (%d)\n", GetLastError());
return GetLastError();
}
// and wait for it to finish
if (WAIT_OBJECT_0 == WaitForSingleObject(hProcess,INFINITE)
{
// child finished
} else
{
// error with wait
printf("WaitForSingleObject failed (%d)\n", GetLastError());
return GetLastError();
}
...
Child process:
int main(int argc, char * argv[])
{
HANDLE hWaitableTimer CreateWaitableTimer(NULL,TRUE,NULL);
if (NULL == hWaitableTimer)
{
printf("CreateWaitableTimer failed (%d)\n", GetLastError());
return GetLastError();
}
DWORD dwDuration = atoi(argv[1]);
LARGE_INTEGER liDueTime = -10000 * dwDuration;
// waitable timer due time is in 100 nano second units
// negative values indicate relative time
if (!SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0))
{
printf("SetWaitableTimer failed (%d)\n", GetLastError());
return GetLastError();
}
DWORD dwKeepGoing = TRUE;
// enter the "to do" loop while waiting for the timer...
While (dwKeepGoing)
{
switch (WaitForSingleObject(hTimer,0)
{
case WAIT_OBJECT_0:
// duration over,
// optionally finalize "to do" stuff here
// and end child
dwKeepGoing = FALSE;
case WAIT_TIMEOUT:
// do stuff here
break;
case WAIT_FAILED:
// the wait function has failed
printf("WaitForSingleObject failed (%d)\n", GetLastError());
return GetLastError();
}
}
return 0;
}
Noone will kill the process for you, unless you either do it on your own (e.g. from parent process), or the process exits itself.
Note that there is also no such thing as "and return control to the parent application". Once child process is started, both parent and child processes have their own "control" and run simultaneously, consuming CPU time given to the processes by the operating system.
All in all, you decide who will be terminating the process. If you do it from parent process, then once started you keep child process handle and use (not a good idea though) TerminateProcess API toward the child process.
Otherwise, and this is the better one, the child process itself keep looking at runtime and just exits when it's time to do so:
main() {
time_to_exit = now() + N;
while(now() < time_to_exit) {
keep_doing_my_stuff();
}
}

Windows setevent processing

I wonder how setevent is handled internally within Windows.
I have the following situation
Std::thread thread loop which executes while std::atomic == true
Inside the loop is a waitforsingleObject which sleeps infinite in alertable state.
A function stopThread() which does the following:
- Clears the atomic bool
- Calls Setevent on the event object
- Calls thread.join
This often hangs, I get the impression that setevent has still some work to do in the current thread, while join blocks
the current thread.
If I add an additional Boolean in the thread which is set after waitforsinlgleObject and I wait for this to be set before calling join()
Everything seems to work ok.
Code (error checking omitted here)
Init code/declarations:
HANDLE m_WakeupThreadEvent;
std::atomic<bool> m_ReceiverEnabled;
m_WakeupThreadEvent = CreateEvent(NULL, false, false, "RxThreadWakeupEvent" );
Thread code:
while(m_ReceiverEnabled)
{
DWORD rslt = WaitForSingleObjectEx(m_WakeupThreadEvent, INFINITE, true);
// Here some checking for rslt;
}
function code:
m_ReceiverEnabled = true;
SetEvent( m_WakeupThreadEvent )
m_Thread.join()
Is there some explanation for this behavior ? I could not find any details about the operation of setEvent()
One thing I just noticed: Why are you setting m_ReceiverEnabled to true? It should be set to false. I have done this in the code below.
Even if you're certain a race condition is not the root of your problem, you still have a race condition due to using an auto-reset event. Can you fix it, then see if that also happens to take care of your main problem as well? Here is code which uses a manual reset event instead in a race-free manner:
HANDLE m_WakeupThreadEvent;
std::atomic<bool> m_ReceiverEnabled;
m_WakeupThreadEvent = CreateEvent(NULL, TRUE, FALSE, "RxThreadWakeupEvent" );
m_ReceiverEnabled = false;
SetEvent( m_WakeupThreadEvent )
m_Thread.join()
while(true)
{
DWORD rslt = WaitForSingleObjectEx(m_WakeupThreadEvent, INFINITE, true);
ResetEvent(m_WakeupThreadEvent);
if(!m_ReceiverEnabled)
break;
// Here some checking for rslt;
}

Closing a thread with select() system call statement?

I have a thread to monitor serial port using select system call, the run function of the thread is as follows:
void <ProtocolClass>::run()
{
int fd = mPort->GetFileDescriptor();
fd_set readfs;
int maxfd=fd+1;
int res;
struct timeval Timeout;
Timeout.tv_usec=0;
Timeout.tv_sec=3;
//BYTE ack_message_frame[ACKNOWLEDGE_FRAME_SIZE];
while(true)
{
usleep(10);
FD_ZERO(&readfs);
FD_SET(fd,&readfs);
res=select(maxfd,&readfs,NULL,NULL,NULL);
if(res<0)
perror("\nselect failed");
else if( res==0)
puts("TIMEOUT");
else if(FD_ISSET(fd,&readfs))
{//IF INPUT RECEIVED
qDebug("************RECEIVED DATA****************");
FlushBuf();
qDebug("\nReading data into a read buffer");
int bytes_read=mPort->ReadPort(mBuf,1000);
mFrameReceived=false;
for(int i=0;i<bytes_read;i++)
{
qDebug("%x",mBuf[i]);
}
//if complete frame has been received, write the acknowledge message frame to the port.
if(bytes_read>0)
{
qDebug("\nAbout to Process Received bytes");
ProcessReceivedBytes(mBuf,bytes_read);
qDebug("\n Processed Received bytes");
if(mFrameReceived)
{
int no_bytes=mPort->WritePort(mAcknowledgeMessage,ACKNOWLEDGE_FRAME_SIZE);
}//if frame received
}//if bytes read > 0
} //if input received
}//end while
}
The problem is when I exit from this thread, using
delete <protocolclass>::instance();
the program crashes with a glibc error of malloc memory corruption. On checking the core with gdb it was found the when exiting the thread it was processing the data and thus the error. The destructor of the protocol class looks as follows:
<ProtocolClass>::~<ProtocolClass>()
{
delete [] mpTrackInfo; //delete data
wait();
mPort->ClosePort();
s_instance = NULL; //static instance of singleton
delete mPort;
}
Is this due to select? Do the semantics for destroying objects change when select is involved? Can someone suggest a clean way to destroy threads involving select call.
Thanks
I'm not sure what threading library you use, but you should probably signal the thread in one way or another that it should exit, rather than killing it.
The most simple way would be to keep a boolean that is set true when the thread should exit, and use a timeout on the select() call to check it periodically.
ProtocolClass::StopThread ()
{
kill_me = true;
// Wait for thread to die
Join();
}
ProtocolClass::run ()
{
struct timeval tv;
...
while (!kill_me) {
...
tv.tv_sec = 1;
tv.tv_usec = 0;
res = select (maxfd, &readfds, NULL, NULL, &tv);
if (res < 0) {
// Handle error
}
else if (res != 0) {
...
}
}
You could also set up a pipe and include it in readfds, and then just write something to it from another thread. That would avoid waking up every second and bring down the thread without delay.
Also, you should of course never use a boolean variable like that without some kind of lock, ...
Are the threads still looking at mpTrackInfo after you delete it?
Not seeing the code it is hard.
But Iwould think that the first thing the destructor should do is wait for any threads to die (preferably with some form of join() to make sure they are all accounted for). Once they are dead you can start cleaning up the data.
your thread is more than just memory with some members, so just deleting and counting on the destructor is not enough. Since I don't know qt threads I think this link can put you on your way:
trolltech message
Two possible problems:
What is mpTrackInfo? You delete it before you wait for the thread to exit. Does the thread use this data somewhere, maybe even after it's been deleted?
How does the thread know it's supposed to exit? The loop in run() seems to run forever, which should cause wait() in the destructor to wait forever.