QT QEventLoop/QThread how to synchronize on an event loop? - c++

I need a way to know when an event loop has started and when it is about to exit. I am trying to synchronize between threads and there is hard to resolve race condition involving isRunning at the times when the loop starts and when it exits.
I believe for starting I can simply post an event since it will be queued and dispatched once it starts. But for exiting I'm not sure how to handle it. I need some kind of event that will happen just prior to the loop completing.
Is there any way to accomplish this?
The reason I need this is for posting events to the thread. I have a function, a cleanup function in particular, say cleanupObject. This function can be called from any thread and is expected to do cleanup on the object. These objects are owned by a thread with an event loop. If this event loop is running this cleanupObject request has to be processed as an event in that event loop. If the event loop is not running then the cleanup has to be handled differently (this happens during shutdown).
The race exists because isRunning has no synchronization I can use, so while it said true when I called it, it may not longer be running the instant after. I need to know whethere the event I post to the loop will be processed or not, because if it will not be processed I must do cleanup in a different fashion.

Related

Ordered notification of threads waiting on a condition (C++, boost)

Does anyone know of a condition variable class that allows notification of threads waiting for a condition to be notified in the order in which they started waiting?
I'm currently using the boost class condition_variable, but calling condition_variable::notify_one() wakes up a random thread, not the thread that first called condition_variable::wait(). I also tried adding thread ids to a queue before calling condition_variable::wait(), so that I can call condition_variable::notify_all() upon which all waiting threads wake up, check the queue and either wait again or proceed (only one thread, namely the thread first in queue). The problem is that calling notify_all() twice does not guarantee that all threads are waking up twice, thereby losing notifications. Any suggestions?
It is strange that you require threads to be woken in particular order and sounds suspicious about your design. Anyway idea is that you can have queue of condition variables (one per thread) and you would call notify_one() for one from top of the queue. In waiting thread you need to do additional logic to check that it was not sporadically interrupted from wait. Again sounds strange why you need thread to wake up in particular order and you may want to rethink your design.

How can we re-initialize a thread without killing it?

Is there any way, by which we can Re-Initialize a thread without killing it. I want to use the existing thread, but they will again start from the beginning.
Create a class that manages a thread.
In the run method of this class have it wait until some work is assigned to the class in the form of a function pointer or some other class that implements a "work" interface.
Once work is assigned, the thread can stop waiting and execute the work.
Once the work is complete the thread sits and waits until more work is assigned to it.
This allows you to keep the thread running and waiting for work, without having to recreate it when new work comes along.
What y ou are asking for can only be achieved by the logic of your thread function. The thread library/operating system does not know about your logic and cannot possibly know where you want it to go on reinitialization.
Also note that while you can achieve something similar by canceling and starting the thread, thread cancellation is quite often dangerous (you might leak resources) if even possible (thread must hit a cancellation point) and should be avoided in most cases. So you are back at square one: implement logic in the function to detect the event and restart with whatever definition of start you want to use.
You could have two events: restart and stop. Your thread function would wait in a loop for any of them. If it detects restart, it would perform the task and go back waiting for events. If it detects stop, it would simply return.

How to make a new thread and terminate it after some time has elapsed?

The deal is:
I want to create a thread that works similarly to executing a new .exe in Windows, so if that program (new thread) crashes or goes into infinite loop: it will be killed gracefully (after the time limit exceeded or when it crashed) and all resources freed properly.
And when that thread has succeeded, i would like to be able to modify some global variable which could have some data in it, such as a list of files for example. That is why i cant just execute external executable from Windows, since i cant access the variables inside the function that got executed into the new thread.
Edit: Clarified the problem a lot more.
The thread will already run after calling CreateThread.
WaitForSingleObject is not necessary (unless you really want to wait for the thread to finish); but it will not "force-quit" the thread; in fact, force-quitting - even if it might be possible - is never such a good idea; you might e.g. leave resources opened or otherwise leave your application in a state which is no good.
A thread is not some sort of magical object that can be made to do things. It is a separate path of execution through your code. Your code cannot be made to jump arbitrarily around its codebase unless you specifically program it to do so. And even then, it can only be done within the rules of C++ (ie: calling functions).
You cannot kill a thread because killing a thread would utterly wreck some of the most fundamental assumptions a programmer makes. You would now have to take into account the possibility that the next line doesn't execute for reasons that you can neither predict nor prevent.
This isn't like exception handling, where C++ specifically requires destructors to be called, and you have the ability to catch exceptions and do special cleanup. You're talking about executing one piece of code, then suddenly ending the execution of that entire call-stack. That's not going to work.
The reason that web browsers moved from a "thread-per-tab" to "process-per-tab" model is exactly this: because processes can be terminated without leaving the other processes in an unknown state. What you need is to use processes instead of threads.
When the process finishes and sets it's data, you need to use some inter-process communication system to read that data (I like Boost.Interprocess myself). It won't look like a regular C++ global variable, but you shouldn't have a problem with reading it. This way, you can effectively kill the process if it's taking too long, and your program will remain in a reasonable state.
Well, that's what WaitForSingleObject does. It blocks until the object does something (in case of a thread it waits until the thread exits or the timeout elapses). What you need is
HANDLE thread = CreateThread(0, 0, do_stuff, NULL, 0, 0);
//rest of code that will run paralelly with your new thread.
WaitForSingleObject(thread, 4000); // wait 4 seconds or for the other thread to exit
If you want your worker thread to shut down after a period of time has elapsed, the best way to do that is to have the thread itself monitor the elapsed time in some way and then exit when the time is up.
Another way to do this is to monitor the elapsed time in the main thread or even a third, monitor type thread. When the time has elapsed, set an event. Your worker thread could wait for this event in it's main loop, and then exit when it has been raised. These kinds of events, which are used to signal the thread to kill itself, are sometimes called "death events." (Or at least, I call them that.)
Yet another way to do this is to queue a user job to the worker thread, which needs to be in an alterable wait state. The APC can then set some internal state variable which will trigger the death sequence in the thread when it resumes.
There is another method which I hesitate even mentioning, because it should only be used in extremely dire circumstances. You can kill the thread. This is a very dangerous method akin to turning off your sink by detonating an atomic bomb. You get the sink turned off, but there could be other unintended consequences as well. Please don't do this unless you know exactly what you're doing and why.
Remove the call to WaitForSingleObject. That causes your parent thread to wait.
Remove the WaitForSingleObject call?

Stopping an MFC thread

I understand the problem with just killing the thread directly (via AfxEndThread or other means), and I've seen the examples using CEvent objects to signal the thread and then having the thread clean itself up. The problem I have is that using CEvent to signal the thread seems to require a loop where you check to see if the thread is signaled at the end of the loop. The problem is, my thread doesn't loop. It just runs, and the processing could take a while (which is why I'd like to be able to stop it).
Also, if I were to just kill the thread, I realize that anything I've allocated will not have a chance to clean itself up. It seems to me like any locals I've been using that happen to have put stuff on the heap will also not be able to clean themselves up. Is this the case?
There is no secret magic knowledge here.
Just check the event object periodically throughout the function code, where you deem it is safe to exit.
Does your thread ever exit? If so, you could set an event in the thread at exit and have the main process wait for that event via waitforsingleevent. This is best to do with a timeout so the main process doesn't appear to lockup when it's closing. At the timeout event, kill the thread via AfxKillThread. You'll have to determine what a reasonable timeout is, though.
Since you don't loop in the thread this seems to me to be the only way to do this. Of course, you could something like set a boolean flag in the main process and have the thread periodically check this flag, but then your thread code will be littered with "if(!canRun) return;" type code.
If the thread never exits, then AfxKillThread/AfxTerminateThread is the only way to stop the thread.
Locals would be placed on the stack and, hence, WOULD be freed on forcing the thread shut (I think). Destructors won't get called though and any critical sections the thread holds will not get released.
If the thread is ONLY doing things with simple data types on the stack, however, it IS a safe thing to be doing.

Atomic Operation C++

In C++, Windows platform, I want to execute a set of function calls as atomic so that execution doesn't switches to other threads in my process. How do I go about doing that? Any ideas, hints?
EDIT: I have a piece of code like:
someObject->Restart();
WaitForSingleObject(handle, INFINITE);
Now the Restart() function does its work asynchronously, so it returns quickly and when that someObject is restarted it sends me an event from another thread where I signal the event handle on which I'm waiting and thus continue processing. But now the problem is that before the code reaches WaitForSingleObject() part, I receive the restart completion event and I signal the event and after that WaitForSingleObject() never returns since it is not signaled again. That's why I want to execute both Restart() and WaitForSingleObject() as atomic.
This is generally not possible. You can't force the OS to not switch to other threads.
What you can do is one of the following:
Use locks, mutexes, criticals sections or semaphores to synchronize a handful of threads that touch the same data.
Use basic operations that are atomic such as compare-and-exchange or atomic-add in the form of win32 api calls such as InterlockedIncrement() and InterlockedCompareExchange()
You don't want all threads to wait, you just want to wait for the new thread to be done, without the risk of missing the signal. This can be done using a semaphore.
Create a semaphore known by both this code and the code eventually executed by Restart, using CreateSemaphore(NULL,0,1,NULL).
In the code you've shown, you'll still use WaitforSingleObject to wait for your semaphore. When the thread executing the Release code is done with it's work, have it call ReleaseSemaphore.
If ReleaseSemaphore is called first, WaitforSingleObject will let you pass immediately. If WaitforSingleObject is called first, it will wait for ReleaseSemaphore.
MSDN should also help you.
A general solution to lost event race is a counting semaphore.
Are you using PulseEvent() to signal your handle? If so, that's the problem.
According to MSDN,
If no threads are waiting, or if no
thread can be released immediately,
PulseEvent simply sets the event
object's state to nonsignaled and
returns.
So if the handle is signaled before you wait on it, the handle is placed immediately in the nonsignaled state by PulseEvent(). That would appear to be why your are "missing" the event. To correct this, replace PulseEvent() with SetEvent().
With this scenario, though, you may need to reset the event after the wait is complete. This of course depends on if this code is executed more than once during the lifetime of your application. Assuming your waiting thread is the only thread that is waiting on the handle, use CreateEvent() to create an auto reset event. This will automatically reset the handle after your waiting thread is released, making it automatically available for the next time through.
Well, you could suspend (using SuspendThread) all other threads in the process, but I suppose you should rethink design of your program.
This is very easy to fix. Just make sure that the event is the auto-reset event (see the parameters of the CreateEvent) and only call SetEvent to the event handle, never call ResetEvent or PulseEvent or some other things. So the WaitForSingleObject will always return properly. If the event has been already set, the WaitForSingleObject will return immediately and reset the event.
Although I worry about your design in general (ie you are making concurrent tasks sequential, thus losing all the benefits of the hard work to make it concurrent), I think I see the simple solution.
Change your event handle to be MANUAL RESET instead of AUTORESET. (see CreateEvent).
Then you won't miss the signal.
After WaitForSingleObject(...), call ResetEvent().
EDIT:
forget what I just said. That won't work. see comments below.