So generally only the main thread should access the GUI in a MFC application.
However is that a law or just recommended? If I make sure, via critical sections, that only one thread accesses a certain object in the GUI, is it ok then? Or is it a problem if the MAIN thread accesses one part of the GUI while another thread access one. Even if those 2 objects don't affect each other?
The reason I ask is because this simplifies my rewrite of the application a lot if I can access the GUI from another thread.
Don't do it. You'll live in a world of ASSERTs and weird behaviour if you do. The GUI works through a system of Windows messages which are 'pumped' on the main thread. If you start modifying the UI in another thread you'll have situations where your operation causes other UI messages, which will be handled by the main thread potentially at the same time you're still trying to access the UI on another thread.
MFC programming is hard enough without trying to handle this sort of thing. Instead use PostMessage to put the UI related handling onto the main thread.
I used to think its almost forbidden to access GUI from a worker thread in MFC and is a recipe for disaster. But recently I learned this is not that hard rule if you know what you are doing, you can use worker threads to access GUI. In the Win32 Multithreaded Book the provides an example of a 'self animated control' which is completely drawn in a worker thread.
If I remember correctly the author pretty much said the same thing you said, if you critical sections at the right places you can make accessing GUI thread safe. The reason MFC doesn't do it by itself is for performance reasons.
Related
I would like to have your opinion for this general technical concept. (I am working on microsoft windows OS)
There is a Process, this process creates multiple threads for different tasks.
Main process: it is a windows service written by C# code.
There are several threads that are create inside the main process: Thread_01, Thread_02, ...
Inside Thread_01: There is a Wrapper dll written in managed C++ to consume DLL_01. (DLL_01 is a dll written by me in native C++ code, that provides some APIs: Add, Remove, Connect)
Add and Remove can run very fast, but Connect may take more than 10 seconds and blocks the caller until it finishes.
I am thinking to use std::async to do the Connect function code, and send the result through a callback to the caller (main process).
Is it a good approach? I heard we cannot create or it is better not to create any thread inside inner threads, is it true? If so, how about std::async ?
Any recommendation is appreciated.
Thanks in advance,
None of what you describe makes the use of threads inacceptable for your code.
As usual, threads have issues that need to be cared for:
Data races due to access to shared data.
Problems of ownership of resources is now not just "Who own what?" but "Who and when owns what?".
When a thread is blocked and you want to abort this operation, how do you cancel it without causing issues down the line? In your case, you must avoid calling the callback, when the receiver doesn't exist any more.
Concerning your approach of using a callback, consider std::future<> instead. This takes care of a few of the issues above, though some are only shifted to the caller instead.
The usual scenario, there is an MFC/Win32/WTL/wxWidgets/Qt application that does something useful. It was designed to be single threaded, and there is some logic that handles errors/questions within processing blocks.
So, somewhere deep inside some class, a dialog can be fired that asks the user "Are you sure you want to complete the action?"/"Error with document layout" or something like that.
The problem is the dialog is fired from computationally heavy/strightforward code. Like FFT/image sharpening/file system de-fragmentation function, or something along the lines. Which could be launched in a worker thread easily, if not for the GUI. And would suit there better, as it would avoid GUI stalls that are so annoying for the user.
However, GUI cannot work in a worker thread, and dependency injection is pretty much impossible to do, because it would go down several layers of computational code. In a very unclean way from class interface standpoint, like someclass instance(data_in, data_out, param1, param2, GUI_class_ref) : m_GUI(GUI_class_ref), ... 3 or more levels deep.
Is there a pattern/checklist for such scenarios that can be used to marshall GUI prompts back to main thread and return the result back into the core of the computational code, if the code is split in multiple threads?
You can create synchronization context. It is a queue of commands to be executed by main thread. Worker thread adds command into this queue (which must be locked for single-thread access) and waits. Main thread processes this queue periodically, executes commands (for example, "Cancel operation" dialogs) and notifies worker threads about results.
In C#, this was done with delegates and arguments to call them. In C++, you can go with enum-coded messages to be processed in a switch (like messages in Windows programs.) Or create something with pointers to member functions + object pointer to call them from + arguments to call with.
You are at one classical old code refactoring crossroad. Proper isolation and dependency injection is infeasible, so you are left with making the GUI context globally accessible. That is creating a Singleton. It doesn't necessarily need to be the GUI context directly, so at least some isolation is achieved. It can be some kind of manager which has the GUI context and accepts just specific one purpose calls from the computation code. You could make the GUI thread class a friend of this manager and make the GUI callbacks (upon closing the dialog) private.
I could give more specific ideas what to write as i went through exactly the same challenge (threadization of existing heavy app). But i am confused whether you want only the GUI thread to be running freely, or the background computation as well. The example dialog prompt you gave is confusing as it suggests a decision which needs to be answered to know whether continue at all (which would mean that computation is on hold).
I have made a game, it is written in C++ and directX.
When the user chooses which mission to play the screen goes blank for some time while it load in all the resources. So the user knows the game has not crashed I want to make a loading screen with an animation.
My question is this:
If one thread (the main one) crashes do all threads of that process crash?
Can you destroy a thread from the thread that created it or does the thread have to terminate itself?
I am new to multithreading and have not used it before. Many people say it makes programs unnecessarily complex so is it worth making my program multithreaded just for a loading screen or is there another way of doing it?
If one thread (the main one) crashes do all threads of that process crash?
If the main thread crashes (i.e. the UI thread) obviously the application crashes. If any worker thread crashes, you will get an exception which you can choose to ignore.
Can you destroy a thread from the thread that created it or does the thread have to terminate itself?
Normally the thread itself should terminate itself (i.e. finish execution). Obviously you can signal any secondary thread to stop from the main thread.
I am new to multithreading and have not used it before. Many people say it makes programs unnecessarily complex so is it worth making my program multithreaded just for a loading screen or is there another way of doing it?
You'll have to learn multitasking if you're serious about programming so better now than never.
If one thread (the main one) crashes do all threads of that process crash?
If by 'crash' you mean that an unhandled exception is propagated to the operating system - Yes.
Can you destroy a thread from the thread that created it or does the thread have to terminate itself?
There's TerminateThread, but it's use is not recommended. Better notify the thread that it should terminate and leave the actual cleanup to the thread.
I am new to multithreading and have not used it before. Many people say it makes programs unnecessarily complex so is it worth making my program multithreaded just for a loading screen or is there another way of doing it?
A loading screen is actually a good example of multithreading. I wouldn't, however, create an extra thread to render your loading screen but rather use multiple threads to stream in your resources. Rendering should be done by one thread (that's generally recommended for all DirectX versions).
When a new window is created using CreateEx does its code execute in its own thread or that of its parent (i.e. the thread in which the its instantiating code was executed)? Thanks.
The window doesn't actually run any code on its own, all the code is called from the message loop which is part of your own code. You can run into huge issues trying to interact with the Windows UI with multiple threads, so you should always respond to the messages within a single thread.
CreateWindowEx() does not create a new thread. If you want a new thread you have to call
either _beginthreadex() (usually preferred) or CreateThread().
In case you're wondering, _beginthreadex() is preferred over CreateThread() because the former initializes parts of the CRT that the latter does not.
Windows have thread affinity – see Raymond Chen's article on this matter.
No, create window dont start new thread
Cross-thread GUI stuff usually ends in disaster. The windows libraries actively discourage it by throwing exceptions.
Even if it was allowed, CreateWindowEx could not do this by default because it would be making some very big assumptions about your code (locks, thread safety, etc); and most Windows development is probably still essentially single threaded.
I have a QWebPage created in the main thread (you can't create it anywhere else). I would like to manipulate this page using the QWebElement API introduced in Qt 4.6, but in a separate thread. So that thread would acquire a reference to the page and perform the necessary tree walking and attribute changes I need.
As the Threads and QObjects doc page explains, it is unsafe to manipulate QObjects in threads that don't own them unless the developer can ensure that the QObject in question will not be processing events while this manipulation is going on.
Now, this QWebPage is also being displayed in a QWebView, but the main thread will be blocked while waiting for the worker thread to finish (actually many of them, working on many different pages). Hence, the main event loop will not be running while the operation is in progress.
Thus, I believe the operation to be safe. Am I mistaken? Have I missed something? I'm basically asking for reassurance that this will not blow up in my face...
I do think you're right, and it is safe. At least, you have me convinced :)