I have two threads that use an event for synchronization.
In each thread they use the same call:
::CreateEvent( NULL,TRUE,FALSE,tcEventName )
The producer thread is the one that makes the call first, while the consumer thread makes the call last, so it's technically opening, not creating the event... I assume.
But, when SetEvent is called in the producer thread, the same event never gets triggered in the consumer thread (I'm using WaitForMultipleObjects())
Is there a tool that can tell me if the event is actually getting triggered properly.
Also, when I call CreateEvent() in each thread, the returned handle value is different for each... should they be the same?
Is there a better way to do this that will ensure it will work?
This is on Windows XP using Visual Studio 2005
Edit: I did some more checking and found that calling CreateEvent in the producer thread (the second one to call CreateEvent) sets LastError to 183 (ERROR_ALREADY_EXISTS),
however CreateEvent still returns a handle to the event...what gives? How can it error as already existing but still return a handle? Or is it supposed to do that?
According to the MSDN documentation for CreateEvent,
If the function succeeds, the return value is a handle to the event object. If the named event object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS.
Based on your description, I don't see a problem with what you're doing. There's nothing I see to indicate you're doing something incorrectly. For me, though, I usually create the event once using CreateEvent() and then pass the handle to the thread(s) that I want to be signaled by that event. But there is nothing technically wrong with your approach.
You do realize that WaitForMultipleObjects() returns the index of the first signaled handle in the handles array, right? For example, if your named event is the second one in the list, but the first handle is signaled the vast majority of the time (e.g., by a fast-acting thread or a manual reset event that is signaled but never reset), WaitForMultipleObjects() will always return WAIT_OBJECT_0. In other words, your consumer thread will never see the fact that your named event is signaled because the first handle is "always" signaled. If this is the case, put your named event first in the list.
You don't happen to have the bWaitAll parameter to WaitForMultipleObjects() set to TRUE, do you? If you do, then all of the handles in the handles array have be signaled before the function returns.
Who calls ResetEvent() for your named event? It should be the consumer. It's not accidentally being called by some third-party thread, is it?
These are simply some things to double-check. If the event still doesn't behave as you expect, replace the WaitForMultipleObjects() with WaitForSingleObject() to see if your named event properly signals the consumer thread.
Hope this helps.
If you just use several threads in one process, why don't you pass event handle from one to another? As I know named kernel objects created to share them between processes.
Also you can try to use OpenEvent function to open already created event. This might give some ideas.
Your code should work as you've described it. If the event already exists when you try to create it, you will get a handle to the existing event.
Handles are different per-thread, so you needn't worry if they are different (they should be).
I suggest you simplify a little bit to see if things are working the way you expect. The fact that you're using WaitForMultipleObjects() tells me you have other stuff going on. If you think it's not working, get rid of the other stuff and see if you can figure it out.
In a single process you only have to call CreateEvent once and share the handle returned in all threads.
Also, you do not need to name the Event unless you want external processes to access the event with OpenEvent. In fact, if you name the event, only one copy of your program will be able to call CreateEvent successfully.
Related
This question already has an answer here:
Qt, How to pause QThread immediately
(1 answer)
Closed 5 years ago.
I would like to know how to properly stop a QThread. I havea infinite loop in a thread, and I would like to stop it when I do a specific action :
I have tried :
if (thread->isRunning()){
worker->stop();
thread->terminate();
}
the stop() method set a value to false to go out of my infinite loop.
Furthermore, I don't really understand the difference between quit(), terminate() or wait(). Can someone explain me ?
Thanks.
A proper answer depends on how you actually use QThread and how you've implemented stop().
An intended use case in Qt assumes following model:
You create an object that will do some useful work in response to Signals
You create a `QThread` and move your object to this thread
When you send a signal to your object, it's processed in `QThread` you've created
Now you need to understand some internals of how this is actually implemented. There are several "models" of signals in Qt and in some cases when you "send a signal" you effectively simply call a "slot" function. That's a "direct" slot connection and in this case slot() will be executed in caller thread, one that raised a signal. So in order to communicate with another thread, Qt allows another kind of signals, queued connections. Instead of calling a slot(), caller leaves a message to object that owns this slot. A thread associated with this object will read this message (at some time later) & perform execution of slot() itself.
Now you can understand what's happening when you create and execute QThread. A newly created thread will execute QThread::run() that, by default, will execute QThread::exec() which is nothing, but an infinite loop that looks for messages for objects associated with thread and transfers them to slots of these objects. Calling QThread::quit() posts a termination message to this queue. When QThread::exec() will read it, it will stop further processing of events, exit infinite loop and gently terminate the thread.
Now, as you may guess, in order to receive termination message, two conditions must be met:
You should be running `QThread::exec()`
You should exit from slot that is currently running
The first one is typically violated when people subclass from QThread and override QThread::run with their own code. In most cases this is a wrong usage, but it's still very widely taught and used. In your case it seems that you're violating the second requirement: your code runs infinite loop and therefore QThread::exec() simply doesn't get a control and don't have any chance to check that it needs to exit. Drop that infinite loop of yours to recycle bin, QThread::exec() is already running such loop for you. Think how to re-write your code so it does not running infinite loops, it's always possible. Think about your program in terms of "messages-to-thread" concept. If you're checking something periodically, create a QTimer that will send messages to your object and implement a check in your slot. If you processing some large amount of data, split this data to smaller chunks and write your object so it will process one chunk at a time in response to some message. E.g. if you are processing image line-by-line, make a slot processLine(int line) and send a sequence of signals "0, 1, 2... height-1" to that slot. Note that you will also have to explicitly call QThread::quit() once done processing because event loop is infinite, it doesn't "know" when you processed all the lines of your image. Also consider using QtConcurrent for computationally-intensive tasks instead of QThread.
Now, the QThread::terminate() does stop a thread in a very different manner. It simply asks OS to kill your thread. And OS will simply abruptly stop your thread at arbitrary position in the code. Thread stack memory will be free'd, but any memory this stack pointed to won't. If a thread was owning some resource (such as file or mutex), it won't ever release it. An operation that involve writing data to memory can be stopped in the middle and leave memory block (e.g. object) incompletely filled and in invalid state. As you might guess from this description, you should never, ever call ::terminate() except for very rare cases where keeping running of thread is worse than getting memory & resource leaks.
QThread::wait() is just a convenience function that waits until QThread ceases to execute. It will work both with exit() and terminate().
You can also implement a threading system of your own subclassed from QThread and implement your own thread termination procedure. All you need to exit a thread is, essentially, just to return from QThread::run() when it becomes necessary and you can't use neither exit() nor terminate() for that purpose. Create your own synchronization primitive and use it to signal your code to return. But in most cases it's not a good idea, keep in mind that (unless you work with QEventLoop by yourself), Qt signal and slots won't be working properly in that case.
I have a class Class in which there's a member property HANDLE handle to a thread (We can assume it is set to NULL at that point) . at some point , a method within Class dispatches one of it's own methods Class::threaded() (using another function that is external to the class itself, but it doesn't really matter here) with CreateThread(). The calling thread will then may continue to other function outside of Class.
As CloseHandle() must be called for the HANDLE returned from CreateThread() , I was wondering if calling it from Class::threaded() just before it returns would be a decent solution.
Two basic ways to deal with a thread. Commonly you're interested when the thread terminates, you'll need to keep the handle around so you can find out. And of course you'll close it after you detected termination. Or you don't care, fire-and-forget style, or have additional synchronization objects to signal that the thread function completed and/or you ask it to exit. In which case you simply close the handle as soon as you start it.
Do keep in mind that it is not necessary to keep the handle opened to keep the thread running, in case that's the source of the confusion.
You receive a handle to the thread so you can manage it. If there is no need to it, you can call CloseHandle right away.
Closing the HANDLE will have no terminate the thread, so, it's secure to close it if nothing from the thread is of interest to you.
You can close it as soon as you are through using it. Closing it has no effect on the thread. (The handle is reference counted by OS.)
I have an application wherein multiple threads wait on the same event object to signal. The problem I am seeing appears to be a type of race condition in that sometimes some threads' wait states (WaitForMultipleObjects) return as a result of the event signal and other threads' wait states apparently don't see the event signal because they don't return. These events were created using CreateEvent as manual-reset event objects.
My application handles these events such that when an event object is signaled, its "owner" thread is responsible for resetting the event object's signal state, as shown in the following code snippet. Other threads waiting on the same event do not attempt to reset its signal state.
switch ( dwObjectWaitState = ::WaitForMultipleObjects( i, pHandles, FALSE, INFINITE ) )
{
case WAIT_OBJECT_0 + BAS_MESSAGE_READY_EVT_ID:
::ResetEvent( pHandles[BAS_MESSAGE_READY_EVT_ID] );
/* handles the event */
break;
}
To put it another way, the problem I am seeing appears to be to what is described in the Remarks section for PulseEvent on the MSDN website:
If the call to PulseEvent occurs
during the time when the thread has
been removed from the wait state, the
thread will not be released because
PulseEvent releases only those threads
that are waiting at the moment it is
called. Therefore, PulseEvent is
unreliable and should not be used by
new applications. Instead, use
condition variables.
If this is what is happening, the only solution I can see is for each thread to register its usage of a given event object with that object's owner thread, so that the owner thread can determine when it is safe to reset the event object's signal state.
Is there a better way to do this? Thanks.
Yes there is a better way:
[...] Instead, use condition variables.
http://msdn.microsoft.com/en-us/library/ms682052(v=vs.85).aspx
Look for WakeAllConditionVariable specificly
Why PulseEvent() is Unreliable and What to Do Without It
The auto-reset event is king!
PulseEvent did only appear in Windows NT 4.0. It did not exist in the original Windows NT 3.1. To the contrary, the reliable functions like CreateEvent, SetEvent and WaitForMultipleObjects did exist from start of the Windows NT, so consider using them.
The CreateEvent function has the bManualReset argument. If this parameter is TRUE, the function creates a manual-reset event object, which requires the use of the ResetEvent function to set the event state to non-signaled. This is not what you need. If this parameter is FALSE, the function creates an auto-reset event object, and system automatically resets the event state to non-signaled after a single waiting thread has been released.
These auto-reset events are very reliable and easy to use.
If you wait for an auto-reset event object with WaitForMultipleObjects or WaitForSingleObject, it reliably resets the event upon exit from these wait functions.
So create events the following way:
EventHandle := CreateEvent(nil, FALSE, FALSE, nil);
Wait for the event from one thread and do SetEvent from another thread. This is very simple and very reliable.
Don’t' ever call ResetEvent (since it automatically reset) or PulseEvent (since it is not reliable and deprecated). Even Microsoft has admitted that PulseEvent should not be used. See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684914(v=vs.85).aspx
This function is unreliable and should not be used, because only those threads will be notified that are in the "wait" state at the moment PulseEvent is called. If they are in any other state, they will not be notified, and you may never know for sure what the thread state is. A thread waiting on a synchronization object can be momentarily removed from the wait state by a kernel-mode Asynchronous Procedure Call, and then returned to the wait state after the APC is complete. If the call to PulseEvent occurs during the time when the thread has been removed from the wait state, the thread will not be released because PulseEvent releases only those threads that are waiting at the moment it is called.
You can find out more about the kernel-mode Asynchronous Procedure Calls at the following links:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms681951(v=vs.85).aspx
http://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590
http://www.osronline.com/article.cfm?id=75
We have never used PulseEvent in our applications. As about auto-reset events, we are using them since Windows NT 3.51 and they work very well.
What to Do when Multiple Threads Waiting for a Single Object
Unfortunately, your case is a little bit more complicated. You have multiple threads waiting for an event, and you have to make sure that all the threads did in fact receive the notification. There is no other reliable way other than to create own event for each thread.
You wrote theat "the only solution I can see is for each thread to register its usage of a given event object with that object's owner thread". This is correct.
You also wrote that "the owner thread can determine when it is safe to reset the event object's signal state" - this is impractical and unsafe. The best way is to use the auto-reset events, so they will reset themselves automatically.
So, you will need to have as many events as are the threads. Besides that, you will need to keep a list of registered threads. So, to notify all the threads, you will have to do SetEvent in a loop for all the event handles. This is a very fast, reliable and cheap way. Events are much cheaper than threads. So, the number of threads is an issue, not the number of events. There is virtually no limit on the kernel objects - the per-process limit on kernel handles is 2^24.
Use conditional variable as in PulseEvent description. The only problem is that native conditional variable on windows was implemented starting from Vista so older system like XP doesn't have it. But you can emulate conditional variable using some other synchronization objects (http://www1.cse.wustl.edu/~schmidt/win32-cv-1.html) but I think the easiest way is to use conditional variable from boost library and its notify_all method to wake up all threads (http://www.boost.org/doc/libs/1_41_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref)
Another possibility (but not very beautiful) is to create one event for each thread and when right now you have PulseEvent you can call SetEvent for all of them. For this solution probably auto-reset events would work better.
In my code, I use QueueUserAPC to interrupt the main thread from his current work in order to invoke some callback first before going back to his previous work.
std::string buffer;
std::tr1::shared_ptr<void> hMainThread;
VOID CALLBACK myCallback (ULONG_PTR dwParam) {
FILE * f = fopen("somefile", "a");
fprintf(f, "CALLBACK WAS INVOKED!\n");
fclose(f);
}
void AdditionalThread () {
// download some file using synchronous wininet and store the
// HTTP response in buffer
QueueUserAPC(myCallback, hMainThread.get(), (ULONG_PTR)0);
}
void storeHandle () {
HANDLE hUnsafe;
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &hUnsafe, 0, FALSE, DUPLICATE_SAME_ACCESS);
hMainThread.reset(hUnsafe, CloseHandle);
}
void startSecondThread () {
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AdditionalThread, 0, 0, NULL);
}
storeHandle and startSecondThread are exposed to a Lua interpreter which is running in the main thread along with other things. What I do now, is
invoke storeHandle from my Lua interpreter. DuplicateHandle returns a non-zero value and therefore succeeds.
invoke startSecondThread from my Lua interpreter. The additional thread gets started properly, and QueueUserAPC returns a nonzero value, stating, that all went well.
as far as I understood QueueUserAPC, myCallback should now get called from the main thread. However, it doesn't.
If QueueUserAPC is the correct way to accomplish my goal (==> see my other question):
How can I get this working?
If I should some other method to interrupt the main thread:
What other method should I use? (Note that I don't want to use pull-ing method in the main thread for this like WaitForSingleObject or polling. I want that the additional thread push-es it's data straight into the main thread, as soon as possible.)
Yeah, QueueUserAPC is not the solution here. Its callback will only run when the thread blocks and the programmer has explicitly allowed the wait to be alertable. That's unlikely.
I hesitate to post the solution because it is going to get you into enormous trouble. You can implement a thread interrupt with SuspendThread(), GetThreadContext(), SetThreadContext() and ResumeThread(). The key is to save the CONTEXT.Eip value on the thread's call stack and replace it with the address of the interrupt function.
The reason you cannot make this work is because you'll have horrible re-entrancy problems. There is no way you can guess at which point of execution you'll interrupt the thread. It may well be right in the middle of it mutating state, the state that you need so badly that you are contemplating doing this. There is no way to not fall into this trap, you can't block it with a mutex or whatnot. It is also extremely hard to diagnose because it will work so well for so long, then randomly fail when the interrupt timing just happens to be unlucky.
A thread must be in a well known state before it can safely run injected code. The traditional one has been mentioned many times before: when a thread is pumping a message loop is is implicitly idle and not doing anything dangerous. QueueUserAPC has the same approach, a thread explicitly signals the operating system that it is a state where the callback can be safely executed. Both by blocking (not executing dangerous code) and setting the bAlertable flag.
A thread has to explicitly signal that it is in a safe state. There is no safe push model, only pull.
From what I can understand in MSDN, the callback is not invoked until the thread enters an alertable state, and this is done by calling SleepEx, SignalObjectAndWait, WaitForSingleObjectEx, WaitForMultipleObjectsEx, or MsgWaitForMultipleObjectsEx.
So if you really don't want to do some polling, I don't think this method is adapted to your case.
Is it possible to implement a "message pump" (or rather an event listener) in your main thread and to delegate all its current work to another thread ? In this case, the main thread waits for any event that are set by the other threads.
The Mac build of my (mainly POSIX) application spawns a child thread that calls CFRunLoopRun() to do an event loop (to get network configuration change events from MacOS).
When it's time to pack things up and go away, the main thread calls CFRunLoopStop() on the child thread's run-loop, at which point CFRunLoopRun() returns in the child thread, the child thread exits, and the main thread (which was blocking waiting for the child thread to exit) can continue.
This appears to work, but my question is: is this a safe/recommended way to do it? In particular, is calling CFRunLoopStop() from another thread liable to cause a race condition? Apple's documentation is silent on the subject, as far as I can tell.
If calling CFRunLoopStop() from the main thread is not the solution, what is a good solution? I know I could have the child thread call CFRunLoopRunInMode() and wake up every so often to check a boolean or something, but I'd prefer not to have the child thread do any polling if I can avoid it.
In the case of CFRunLoopStop - if it could only be called safely on the current run loop, then it would not be necessary to pass it a parameter indicating which run loop to stop.
The presence of the parameter is a strong indication that its ok to use it to stop run loops other than the current run loop.
In particular, is calling CFRunLoopStop() from another thread [safe]?
Here's what Run Loop Management says:
The functions in Core Foundation are generally thread-safe and can be called from any thread.
So maybe CFRunLoopStop is safe. But I do worry about their use of the word “generally”. My rule is: If Apple doesn't say it's safe, you should assume it's not.
To err on the safe side, you might consider creating a run loop source, adding that to your run loop, and signaling that source when it's time to end the thread. That same document includes an example of a custom run loop source.