Qt undo/redo and threads - c++

In my MDI application I use the Qt undo/redo framework and it works very well.
Now I have implemented an operation that requires a lot of time, so I would like to run it in another thread so that the application is not freezed and the user can work on the other MDI windows meanwhile.
So I have to run the operation in a new thread inside the redo() method of my QUndoCommand. This is a problem, because:
If I wait inside the redo() method that the thread has finished, the application freezes, so it is useless.
If I don't wait that thread has finished, the redo() method returns before the operation is completed, and this can cause a lot of problems and errors (e.g. if the user uses the undo/redo mechanism, it is possible that the commands following the thread command are executed before it is completed).
Any idea?

You have much bigger problems than undo/redo. Change the architecture so that system behavior is sane when asynchronous data processing is underway. The data manager object should indicate when it's busy, and the UI should reflect that. Once you get this working properly, undo/redo will magically work as well.

Related

Converting a Console Program into an MFC app (Thread issues) (Pleora SDK)

Back to stackoverflow with another question after hours of trying on my own haha.
Thank you all for reading this and helping in advance.
Please note the console program has following functionalities:
connect to a frame grabber
apply some configs
store the incoming data (640 * 480 16-bit grayscale imgs) in a stream of buffers inside a while loop
Exits the while loop upon a key press.
disconnect from device
And I'm only adding the displaying the images functionality on the MFC GUI app. In short,
i) Converting a console app to an MFC app (dialog based)
ii) decided to use thread for displaying images, but DK how to properly exit from thread when there are certain tasks to be done (such as call disconnectFromDevice(); freeBuffers();, etc) before exiting the thread.
iii) have tried making the while loop condition false but didn't work
( I actually want this to be a callback function that's called repeatedly but IDK how to implement it inside a thread)
iv) forcing AfxEndThread didn't work and it's not even the way it should be done (I think).
So my question is,
1. Are you supposed to use a while loop to excuete a certain job that should repeatedly be done? If not, do you have to implement a callback inside a thread? Or use Windows message loop? Why and how? Please provide a hello-world-like sample code example
(for example, you are printing "hello world" repeatedly inside a thread with a condtion in an MFC GUI app. How do you update or check the condition to end the thread if you can't just AfxEndThread() inside the threadproc)
2. If it's ok with a while, how do you exit from the while loop, in other words how do you properly update the exit condition outside the thread the while loop's in?
Please refer to the source code in the provided link
ctrl+F OnBnClickedConnectButton, AcquireImages and OnBnClickedDisconnectButton
https://github.com/MetaCortex728/img_processing/blob/main/IR140Dlg.cpp
Worker threads do not have message-queues, the (typically one and only) UI one does. The message-queue for a thread is created by the first call of the GetMessage() function. Why use messages to control processing in a worker thread? You would have to establish a special protocol for this, defining custom messages and posting them to the queue.
Worker threads can be implemented as a loop. The loop can be terminated based on various conditions, like failures to retrieve any data or request from the user. You can simply exit the thread proc to terminate the thread's execution. If the thread doesn't respond it may have stuck (unless it performs a really lengthy operation) and the UI thread must provide some mechanism to kill it. That is first request termination and if it doesn't respond within some set time then kill it.
The condition mechanism to terminate should best be some synchronization object (I would recommend a manual-reset event), interlocked variable or a simple boolean which you should access and set using a critical section.
Some considerations:
You pass a parameter block to the thread. Make sure that it remains alive throughout the thread's lifetime. For example, it should NOT be a local variable in a function that exits before the thread's termination.
The loop must be "efficient", ie do not loop infinitely if data are not available. Consider using blocking functions with timeouts, if available.
Resource management (eg connecting/disconnecting, allocating/releasing etc) should best be performed by the same thread.
An alternative implementation can be APCs. Then the thread's proc function is a while(!bTerminate) { SleepEx(INFINITE, TRUE); } loop, and other threads issue requests using a the QueueUserAPC() function.
The AfxEndThread(0) call in OnBnClickedDisconnectButton() is wrong, it terminates the current thread, which in this case is the main (UI) thread. Check the documentation.
A sidenote, my suggestion about the project type is not a dialog-based application but instead a normal MFC application without a document class (uncheck the Document/View architecture support option), as it offers features like menus, toolbars and the like, and most importantly the ON_UPDATE_COMMAND_UI handlers.

How to clean up a thread within seconds before killing it?

I have a utility which will access the database and clean the garbage files. this is a console application which is being called from another application.
I have a thread from the main thread which will do the tasks while the main thread will be in a loop to check if cancel of the utility has been called.
The functions in the thread call a different dll which takes time. Now, is there any way that when I cancel the thread. Even if it is inside the function, it gets notified to stop immediately and rollback any changes done to the database?
My application is a windows based application and is written in c++. I have tried using TerminateThread() function from Windows but the problem is that is does not allow to do clean up on the thread.

Cross thread call a.k.a run on main/UI thread from other thread without dependencies needed

I'm on some c++ mobile product, but I need my apps main thread is still running without any blocking when doing some heavy work on the background thread and run back on main thread. But I realized there is no runOnMainThread/runOnUIThread in c++ thread api. I trying to figure it out the issue and found that need to depend library, or create your own thread event queue. Although it is good, but i am thinking to have a behavior which can runOnUIThread.
How it does not work: the mentioned library creates a timer, installs a SIGALRM signal handler and dispatches queued tasks when signals are fired. This allows tasks being processed on the main thread even when it is busy. However POSIX permits only a small set of async-signal-safe functions to be invoked inside of signal handler. Running arbitrary с++ code inside of signal handler violates that restriction and leaves application in hopelessly doomed state.
After some research and development, I've created a library called NonBlockpp
it is a small c++ library to allow c++ mobile application able to process the heavy and time consuming task on background and back to Main thread again, It’s been tested and fired the main thread event.
It also allow to save the tasks and fire them later, all the task has no blocking each other and thread safety.
How it works:
If you found any query or suggestion, please don't hesitate to raise an issue and we can discuss it together.
The project has rectify from signal to pollEvent due to signal handler might not be safe to use.
Please take a look the new changed.
NonBlockpp
Usage

What is the trick to run a member function in the back-end without slowing down the main application?

Sorry I don't know how to phrase this in the title, maybe someone could help me.
I am starting to make a Qt application, let's say, the application will first show N points on the screen. Then we have a function now, called movePoints, when it is called, these points will be moved according to some algorithms.
Now when N is small, everything looks very smooth, it works very well without any problem. But if N is very large, the whole GUI sucks because movePoints is running. So whenever I touch the application window now, it becomes unresponding. But I know lots of programs seem to be able to let the movePoints function run in the back-end (with a progress bar in the status bar or something) without slowing down the main application. How can I achieve this effect?
To keep your application responsive to user interactions, you should use the processEvents function. (http://qt-project.org/doc/qt-4.8/qcoreapplication.html#processEvents)
If you'd rather have the operation occur in the background you can use the QtConcurrent module and use the asynchronous run function (http://qt-project.org/doc/qt-4.8/qtconcurrentrun.html).
Use a QTimer for an interrupt or a QThread to bring the calculation out of the main loop. See: http://qt-project.org/doc/qt-4.8/threads.html
You can use a separate thread to perform calculations in the background without blocking the Qt event loop. See QThread and QConcurrent. It's common practice in processing-intensive Qt applications to have the main thread handle the GUI while "back-end" calculations are done in "worker" threads.
If rendering the data (rather than just calculating the next state) is also an intensive operation, you can also use your worker thread(s) to create a QImage, QGraphicsScene, or similar type of object, and send it pre-built to the UI thread.
If you're limited to a single thread (e.g. your platform doesn't really support threads), then you can take your algorithm and intersperse calls to QCoreApplication::proccessEvents, which will make the GUI more responsive while the activity runs. I find that using actual threads tends to be the simpler and more maintainable approach, though.

QThread doesn't start

Sorry for the length of this post. But I am stuck for two days now....
I am working on a Qt 4.6 Windows application that communicates with a hardware device through ActiveX.
When I send a command, the device does some stuff and when it's done (can take up to one minute) it emits a signal. I need to wait this signal to know if everything went okay (or not) and do some actions in consequence.
A command is sent to the device when a user clicks a button. And obviously, I don't want the HMI to freeze.
I am convinced I have to use threads. So I identified three threads:
the main thread corresponding to the HMI
the hardware controller (which locks after a command is sent and waits a signal)
a hardware notification listener that continuously gets signals from the hardware and unlock the thread 2
Here is the class diagram:
And a sequence diagram to show how I see things:
Explanations:
When the user launches my application, the HMI is created. The constructor of the HMI calls the constructor of the Worker. It constructs the hardware QAxObject. Then it constructs the HardwareListener giving in reference: the QAxObject, the QMutex and the QWaitCondition. Then the constructor of the Worker moves the HardwareListener object to another thread and starts it. Finally, the constructor of the HMI starts the thread of the Worker.
Then, when the user clicks a button, the HMI sends a signal to the Worker. The Worker sends a command to the hardware (that command may block the thread several seconds that's why I need the HardwareListener in another thread not to miss a signal). Then the Worker waits for a QWaitCondition (after having locked the QMutex).
After that, the hardware device sends a signal to the HardwareListener which wakes up the QWaitCondition. Therefore, the Worker thread stops waiting and finishes its actions. Finally, the Worker informs the HMI.
Problem:
The Worker and HardwareListener threads aren't created/started. Everything is done in the main thread so, obviously, it doesn't work. I don't exchange any special object between threads (so no need for qRegisterMetaType())
Question:
Is my design acceptable? There may be some other ways to do but it seems to me this is the most straightforward (taking into account the complexity).
EDIT:
I've changed my code to remove the QThread inheritance. I use the moveToThread() method instead.
Now the threads work fine. HOWEVER I have an ActiveX error: QAxBase: Error calling IDispatch member NewProject: Unknown error.
It seems the interfacing with the hardware is broken... Any idea?
Here is something interesting:
You cannot move a QAxObject to another thread once it has been created.
SOLUTION:
Here is what I have found.
Inheriting from QThread is not good design. If the work you are doing is computational heavy I would recommend using QThreadPool. I not than its better to use an asynchronous design. This means only calling function which never block and instead connect to signals notifying you that something happened.
So for example sending the command to the hardware and emitting a signal once the hardware is done. If the hardware API doesn't supply async functions than you are stuck with using threads.
QtConcurrentRun can help with that. Usually you should not need to touch threads yourself; and its a hell of a lot easier without.