-
WinAPI wrapper classes
Hey all, I've heard it said that ideally a Win32 app's message pump should be placed in a separate thread. However, from my point of view this would create far more problems than it would solve.
-You would have to create/initialize the window from the worker thread: more work for you.
-You would have to worry about thread synchronization whenever responding to events such as a button click, repaint, keyboard, etc.: more headache for you.
-You would have to worry about init and cleanup of a thread, rather than just terminating the message loop and quitting: more work for you.
-Unless you thread sync, virtually nothing can be done in the original thread; But if the GUI thread is waiting on a sync object while your main thread does something slowly, you've just lost any potential benefit.
-You can reproduce much the same effect by placing mini-messagepumps in your functions that block.
The only advantage I can think of, is in the event of you wanting to use GetMessage() and another non-user-defined blocking function at the same time; but few functions (Winsock excluded) will block for a noticeable amount of time, and if polling/asynchronous is an option (like in Winsock :rolleyes: ) then you can switch to "PeekMessage(), then poll other", with a Sleep(1); thrown in there to prevent eating all the CPU time.
Can anyone give me a better, solid example of why you'd want to separate your message loop from your main thread? :confused:
Thanks.
-
>> -You would have to create/initialize the window from the worker thread: more work for you.
True, but work you'd have to do anyways.
>> -You would have to worry about thread synchronization whenever responding to events such as a button click, repaint, keyboard, etc.: more headache for you.
Not typically. These are the responsibilities of a message-loop thread and there shouldn't be other threads interfering with these responsibilities.
>> -Unless you thread sync, virtually nothing can be done in the original thread
There's nothing wrong with two threads doing something at the same time as long as the threads synchronize when needed.
>> -You can reproduce much the same effect by placing mini-messagepumps in your functions that block.
True.
Most of the time you can write your Windows apps so that the main thread takes care of the message loop for the entire application - and any created threads perform processing in the background.
Sometimes it makes sense to seperate a window or group of windows into a seperate UI message-loop thread. A good example would be an MDI implementation like the one Excell and MS-Word use - in that each open document gets it's own UI thread which is responsible for an open document window on the taskbar.
gg
-
>>Not typically. These are the responsibilities of a message-loop thread and there shouldn't be other threads interfering with these responsibilities.
Right, but GUI events typically signify:
-You want the program to do something -> access data that the main thread is using
-You want the program to display data -> access data that the main thread is modifying
If the window procedure has to display data that the main thread is using, i.e. tying up with a blocking operation, then we've still got a message clog as we wait for the main thread to finish up and release control; and if a buttonclick is supposed to trigger a lengthy operation, then we'll have a message clog again (especially if the button event also needs access to that data we're sitting on). Unless, I suppose you might just spawn another worker thread to handle the buttonclick?
The MDI example makes more sense to me though, since each window/thread acts as more or less an independent, self-contained application with little or no data sharing; and the main thread just acts as the glue and slavedriver, sticking them all together and telling them to open or close.
-
If you have to wait for access to a resource not under your control then there's not much you can do except show a "pleas wait" dialog with a cancel button to the user.
Shared resources will have to be synchronized with respect to thread access, but any "clogs" that occur between your own threads are usually the programmers fault.
>> then we've still got a message clog as we wait for the main thread to finish up and release control
So in this situation, the clog occurs because who ever implemented the main thread is hog'n resources for too long ;) (I say "too long" because anything less wouldn't be a "clog").
Use a worker thread when you want to perform a background task asynchronous to user input or any other message.
Use a GUI thread when you want to dedicate a message pump to one ore more windows in your application.
gg
-
>>Use a worker thread when you want to perform a background task asynchronous to user input or any other message.
Sounds good :)
>>when you want to dedicate a message pump to one or more windows in your application.
Isn't that the same thing as "Use a GUI thread when you want to put the message pump for a window in a separate thread"? :confused:
-
Yes, that's the same thing.
>> I've heard it said that ideally a Win32 app's message pump should be placed in a separate thread.
I wouldn't say it's "ideal", but using GUI threads does have its place. Personally, I tend to solve most problems using a single GUI thread and zero or more worker threads.
Regardless of how many GUI threads you have, each GUI thread needs to stay responsive to user input. If processing a message takes "too long" such that user input is ignored or delayed, then that processing might belong in a worker thread.
gg
-
>>Yes, that's the same thing.
And circular logic is good because it is :)
By 'a single GUI thread', are you referring to your main thread, or do you still spawn a separate thread for your GUI?
>>Regardless of how many GUI threads you have, each GUI thread needs to stay responsive to user input. If processing a message takes "too long" such that user input is ignored or delayed, then that processing might belong in a worker thread.
Sounds logical.
-
Yes, I was refering to the main()/WinMain() thread as the primary GUI thread.
gg
-