I have a multi-threaded simulation running on Windows Vista. When I use PostThreadMessage to send messages between threads, I am getting ERROR_INVALID_THREAD_ID, even though I am quite certain (from stepping through the debugger) that the thread id is valid, and the thread has a message queue, since I call PeekMessage from every thread after I create them, as specified in MSDN. It's likely the target thread is suspended, but that should not be a problem, as far as I can tell.
Any clues on what to try? I am simulating an RTOS based application, so I'm hoping not to have to put in too much Windows specific code.
EDIT -
Another clue - if I remove all the semaphore blocking, the messages work fine (although there are some known race conditions). But message queues should not be affected by thread blocking, right?
Edit 2
The code also has the following retry mechanism, as suggested by MSDN. But it still does not work - the retry always fails. hmmm.....
BOOL bResult = false;
int retry = 0;
DWORD dwError = 0;
do
{
bResult = PostThreadMessage(pTaskHandle->dwThreadID,0,0,(LPARAM)pMessage);
if (!bResult)
{
dwError = GetLastError();
retry++; // should only happen once, if the dest thread has no msg queue
// the retry establishes the queue
Sleep(500);
}
} while (!bResult && retry<3); // MSDN says try this a few times to start msg queue
You mention you call PeekMessage after creating the threads but do these threads have full, active message processing loops that are dispatching the messages? msdn says:
Call PostThreadMessage. If it fails, call the Sleep function and call PostThreadMessage again. Repeat until PostThreadMessage succeeds.
which sounds a little goofy if the only requirement is that the thread called PeekMessage once.
Also be aware that messages posted via. PostThreadMessage don't get dispatched in DispatchMessage. this seems obvious since there's no window for the message to go to, but I've seen people do it, especially when using MsgWaitForMultipleObjects and such to wait on a handle. in this case it seems unlikely you'd get ERROR_INVALID_THREAD_ID... more likely you'd just miss the message.
Related
This is windows specific question.
According to microsoft docs,
The system maintains a single system message queue and one thread-specific message queue for each GUI thread. To avoid the overhead of creating a message queue for non–GUI threads, all threads are created initially without a message queue. The system creates a thread-specific message queue only when the thread makes its first call to one of the specific user functions; no GUI function calls result in the creation of a message queue.
So far I believed on that all threads are created initially without a message queue. Today, I tested this with PostThreadMessageW because it is stated that
The function fails if the specified thread does not have a message queue.
However, PostThreadMessageW always returns 1 (TRUE) for all threads right after creation.
DWORD dwThreadID = GetCurrentThreadId();
BOOL bResult = PostThreadMessageW(dwThreadID, WM_QUIT, 123, 456);
Why is this happening?
So I am trying to understand the message processing code of Unreal Engine on Windows OS, and I didn't find any frequent usage of the function MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx in the message pumping code.
The engine message pumping goes like this:
MSG Message;
// standard Windows message handling
while(PeekMessage(&Message, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
For context, this code will run every frame one to three times, meaning the code will be executed each 2 - 5 milliseconds on average throughout the running time of the application. A) Does that make wait functions unnecessary? or am I missing something here!
B) Is there any rough estimation of how long an application could be busy doing 'other stuff' before processing incoming messages? For instance if an application only processes messages every 50 millisecond, is that a bad practice? or is that a reasonable way of doing it? And what if the period became 500 milliseconds and so?
Use MsgWaitForMultipleObjects/etc if you need to both handle window message processing and kernel handle or alertable waits in a single thread. If you are only doing message processing then simply use a normal GetMessage based message loop, if only doing kernel handle or alertable waits then use WaitForMultipleObjects as appropriate.
Everyone probably knows the code to run a program and wait for it to end:
CreateProcess(...
WaitForSingleObject(Process.hProcess, INFINITE
It was used several times by myself. But recently I found that this call when it launches a program with a multimedia playback has worse performance than the same process being executed from a general file manager (Windows XP). That's ok with CPU consumption of my (parent) process, but while playing the fragment there are unexpected little stops.
I made a little change to something like:
CreateProcess ...
do {
Sleep(100);
Res = WaitForSingleObject(Process.hProcess, 10);
} while (Res == WAIT_TIMEOUT);
And it helped. Now the child process plays the fragment without problems.
So what's wrong with the first fragment and is it documented somewhere? As I see from the tests the second "wait" is more "relaxed" than the first one, but the first one doesn't eat CPU at least formally
If this code is running on a UI thread, you will cause performance problems with other processes that (directly or indirectly) send messages to your window(s), since you do not run the message loop while you are waiting for the child process. Neither Sleep() nor WaitForSingleObject() will process messages.
Windows Explorer (the file manager) will not suffer this problem because it:
Does not keep an open handle to processes it launches at the user's request (I think this is more likely, since Explorer needs neither to know when the process exits or its exit code), or
Does not wait on any open process handles it may keep from its children, and importantly
Always makes sure to run a message loop while it waits on handles. This is very important in any process that makes use of COM, which Explorer uses heavily.
Instead of calling WaitForSingleObject(), you can call MsgWaitForMultipleObjects(). If you specifiy QS_ALLINPUT for the dwWaitMask parameter, MsgWaitForMultipleObjects will return either when your event is signaled or when there is input in the thread's message queue. If MsgWaitForMultipleObjects() returned because a message is available, you can process it and resume waiting:
MSG msg;
DWORD reason = WAIT_TIMEOUT;
while (WAIT_OBJECT_0 != reason) {
reason = MsgWaitForMultipleObjects(1, &hChildProcess, FALSE, INFINITE, QS_ALLINPUT);
switch (reason) {
case WAIT_OBJECT_0:
// Your child process is finished.
break;
case (WAIT_OBJECT_0 + 1):
// A message is available in the message queue.
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
// Note that if your main message loop does additional processing
// (such as calling IsDialogMessage() for modeless dialogs)
// you will want to do those things here, too.
}
break;
}
}
There are a few options here, probably, but what would you suggest to be the safest way to accomplish the following:
I've got a child CFrameWnd with a parent = NULL (so that it can live a separate life from the main application, while the app is running, at least). I've got all those windows stored in a list. When the main app is closing (MainFrame getting an OnClose), I go through the array and issue a PostMessage(WM_CLOSE) to all. However, the problem is that each of them has to do stuff before closing down. So, I need to wait for them. But we're all on the same thread... So, how can I wait for the children to close, without blocking their own processing in a single-threaded application?
Or should I launch a worker thread to take care of that? Would it be easier?
Thanks in advance!
Use SendMessage() instead of PostMessage().
Edit: Another option might be to simply handle WM_DESTROY in your child windows (depending on your code of course).
Well you certainly can't just wait for them to close, you need to at least pump messages so that they would receive and handle the WM_CLOSE. How you do that is up to you I guess. But I see you are doing PostMessage. Why not do SendMessage instead - this will run the close synchronously in the window procedure for the window. Or are you trying to quit the app? Then you should really use PostQuitMessage then pump messages in the normal fashion until GetMessage returns 0. Lots of options.
Pumping messages means to have a loop in your code that looks like this. You don't have to call AfxPumpMessages, but that would probably do something similar. There are in fact many different ways to pump messages depending on what you want to do. In addition there are quite a few functions that pump messages for you.
BOOL bRet;
// note that GetMessage returns 0 when WM_QUIT is received - this is how PostQuitMessage
// would work to get us to shut down
// We are passing NULL for the hWnd parameter - this means receive all window and
// thread messages for this thread
while( (bRet = GetMessage( &msg, NULL /* hWnd */, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
If you post the message to a window or windows, then you need to pump messages. What happens is that the message goes into a queue for the thread associated with that window (this thread) - the message pump extracts them out and dispatches them off to the correct window procedure.
If you had sent the message instead of posting it, then the window procedure for the window is called directly - rather than going into a queue. You wouldn't need to pump messages because once SendMessage returns the message is fully handled.
The way PostQuitMessage works is by setting a flag on the message queue indicating that the application should quit. The WM_QUIT message isn't really a window message that you would send - what happens is that GetMessage will check this flag after all the other posted window messages are processed and returns 0 if it is set. This will cause all windows to correctly close, and you don't need to send it to the windows themselves.
I am currently using CreateProcess/WaitForSingleObject from within a win32 GUI app to launch a small GUI app that deals with software licensing issues. This all works fine, but it essentially hangs the "parent" app while it waits for the licensing app to finish its work. During this time, updates to the parent app do not occur and it ends up with ugly white squares if the utility app window is moved.
Also, for some strange reason, while the utility app is running, if I copy something from within that app to the clipboard, it HANGS. I haven't figured out why yet, but it only happens if I am waiting for the app to finish from within the parent app.
So I'm thinking that if I can cause the parent app to handle its events while waiting for my other app to finish, it might solve both problems.
So, is there a replacement for CreateProcess/WaitForSingleObject that also handles UI updates?
Your parent process appears to hang because the WaitForSingleObject() call blocks your thread until the handle you pass into the call is signaled.
Your child process likely hangs during the copy-to-clipboard operation because it is, as a part of that operation, sending a message either specifically to the parent process's window or to all top-level windows. The message loop in your parent process's thread is not running, because it is blocked waiting until the child process exits, so the message is never processed and the child process remains blocked.
Instead of calling WaitForSingleObject(), you can call MsgWaitForMultipleObjects(). If you specifiy QS_ALLINPUT for the dwWaitMask parameter, MsgWaitForMultipleObjects will return either when your event is signaled or when there is input in the thread's message queue. If MsgWaitForMultipleObjects() returned because a message is available, you can process it and resume waiting:
MSG msg;
DWORD reason = WAIT_TIMEOUT;
while (WAIT_OBJECT_0 != reason) {
reason = MsgWaitForMultipleObjects(1, &hChildProcess, FALSE, INFINITE, QS_ALLINPUT);
switch (reason) {
case WAIT_OBJECT_0:
// Your child process is finished.
break;
case (WAIT_OBJECT_0 + 1):
// A message is available in the message queue.
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
// Note that if your main message loop does additional processing
// (such as calling IsDialogMessage() for modeless dialogs)
// you will want to do those things here, too.
}
break;
}
}
You could put the WaitForSingleObject call in a loop and use a relatively small value for the dwMilliseconds parameter.
The condition to exit the loop is when the WaitForSingleObject call returns WAIT_OBJECT_0.
In the loop you have to examine the message queue to see if there are any that you must process. How you handle this is really up to you an it depends on your typical needs.
// Assuming hYourWaitHandle is the handle that you're waiting on
// and hwnd is your window's handle, msg is a MSG variable and
// result is a DWORD variable
//
// Give the process 33 ms (you can use a different value here depending on
// how responsive you wish your app to be)
while((result = WaitForSingleObject(hYourWaitHAndle, 33)) == WAIT_TIMEOUT)
{
// if after 33 ms the object's handle is not signaled..
// we examine the message queue and if ther eare any waiting..
// Note: see PeekMessage documentation for details on how to limit
// the types of messages to look for
while(PeekMessage(&msg, hwnd, 0, 0, PM_NOREMOVE))
{
// we process them..
if(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
// if you're here it means WaitForSingleObject returned WAIT_OBJECT_0, so you're done
// (but you should always check and make sure it really is WAIT_OBJECT_0)
if(result != WAIT_OBJECT_0)
{
// This should not be.. so react!
}
I suggest you can handle this as follows:
Parent application does CreateProcess, and then returns immediately instead of waiting for a response or for the utility app to finish
Because the parent applicatin has returned, it can handle other Window messages (e.g. WM_PAINT)
When the utility app finishes, it notifies the parent application (e.g. using PostMessage and RegisterWindowMessage APIs)
Parent application handles positive notification received via PostMessage
Parent application may also have a Windows timer (WM_TIMER) running, so that it knows if the utility app is killed before it send its notification
You can get a hanging problem if the app you are spawning causes a sendmessage broadcast, either explicit or implicit. This is clipped from my website:
The problem arises because your application has a window but isn't pumping messages. If the spawned application invokes SendMessage with one of the broadcast targets (HWND_BROADCAST or HWND_TOPMOST), then the SendMessage won't return to the new application until all applications have handled the message - but your app can't handle the message because it isn't pumping messages.... so the new app locks up, so your wait never succeeds.... DEADLOCK.
I don't do clipboard code, but if that causes the situation above (believeable), then you'll deadlock. You can:
put the launch of the secondary application into a little thread
use a timeout and spin around a PeekMessage loop (yuck)
use the MsgWaitForMultipleObjects API.
No preference is implied by that ordering... I'm assuming you don't create the spawned application yourself, in which case you could use IPC to get around this issue, as ChrisW suggested.
You should create a thread that does only the following:
call CreateProcess() to run the other app
call WaitForSingleObject() to wait for the process to finish - since this is a background thread your app will not block
call CloseHandle() on the process handle
call PostMessage() with a notification message for your main thread
Now you only need to make sure that your main application has its GUI disabled to prevent reentrancy problems, possible by showing a modal dialog that informs the user that the other app is running and needs to be dealt with first. Make sure that the dialog can not be closed manually, and that it closes itself when it receives the posted notification message from the background thread. You can put the whole thread creation into this dialog as well, and wrap everything in a single function that creates, shows and destroys the dialog and returns the result your external application produces.