I know that it's bad to run any kind of GUI widget from within a separate thread. For just messages, this can be overcome with signals to the main thread. But what if the thread needs a user input, how can the answer be signaled back to the thread and how can that thread wait for that answer?
My particular case is an application that uses sftp from libssh. During connection and authentication, the user may need to answer one or more questions. But for performance reasons, all the SSH/SFTP stuff must be running in a separate thread.
It is not possible to use GUI classes in non-GUI threads at all. What you can do is use signals and slots to exchange information from one thread to another. Send a signal from your worker thread and wait on a semaphore, like QWaitCondition. Send a message back with the answer.
In your case you could also use Qt::BlockingQueuedConnection as connection type to stop your worker thread until the user has entered data. QInputDialog also waits until the user has finished entering data.
Related
More precisely, the question should be:
What's the difference between connecting the signal QTimer::timeout to my working function and creating a worker thread with QThread?
I am writing a program which receives streaming data in main thread (the signal is generated by QIODevice::readread())and processes them concurrently. For now I start a QTimer constantly firing signal QTimer::timeout, and the signal is connected to a working function in main thread which does the data processing stuff. This is how I achieve the concurrency.
I wonder if this approach different from creating another thread with QThread, since the idea I've found in this topic is very simliar to what I've done. The only difference is that the accepted answer creates another thread and moves timer and worker class on it. Besides the difference, I can't see any necessity of using a thread in my case.
In my case (receiving data in main thread and processing them concurrently), am I doing OK using QTimer or should I create a QThread? I am quite new to multi-threading, and if I misunderstand something, please help correct me. Thank you.
[Edit]:
I don't know what's the difference/advantage of creating a new thread to process the data. For now, everything is doing in one thread: I keep storing data in a queue and dequeue them one by one in a function triggered by QTimer::timeout.
What's the difference between connecting the signal QTimer::timeout to my working
function and creating a worker thread with QThread?
When you connect some signal/slot pair from the objects which has the same thread affinity, then the connection is direct. What it means is in your case, the main thread creates the timer, and also contains the slot, so the signal will be emitted in the main thread and also will be processed in the main thread (as the slot is also in the main thread).
When you connect some signal/slot pair from the objects which has the different thread affinity, then the connection is queued. That means signal emission and slot execution will run in different threads.
You are not really achieving concurrency, the timer signal and processing slot are executing in main thread sequentially.
So here are your options:
If you want to process data in main thread, current code is ok.
If you want to emit timeout in main thread and process data in different thread then create new class with the processing method and use moveToThread with object of that class.
The link you provided really has a different situation. In your case (correct me if I am wrong), you process data only when data is available, not just after a specified time. Your situation is much like traditional producer/consumer problem. My proposal is to not use QTimer at all. Instead create a new class with a slotwhich will process data. Then emit a signal from main thread when data is available, and connect if to the processing slot. You will achieve real concurrency. In this case you will need to implement locking for shared data access, it is easy in Qt, you can just use QMutexLocker
First, a little background:
One of the fundamental ideas behind threads is that a thread can only do one thing at a time. It may be updating the GUI, or processing data, or communicating with a remote server, but it can't be doing all those things at once.
That's where multi-threading comes in. You probably want your computer to be doing many things at once (watching videos, browsing the web, listening to music, and writing code all at the same time). The computer allows you to do that by scheduling each of these tasks on a separate threads and switching between them in periodic intervals.
In the old days, before multi-core processors, this was achieved solely by multitasking (the processor would interrupt the currently executing thread, switch to another thread context and execute the other thread for a while before switching again). With modern processors, you can have several threads executing at the EXACT same time, one on each core. This is typically referred to as multiprocessing.
Now, back to your question:
A thread can only do one thing at a time and, if you use a timer, you are using the main (AKA GUI) thread to process your data. This thread is typically responsible for responding to OS events and updating the GUI (hence GUI thread). If you don't have a lot of data to process, it's typically OK to do so on the GUI thread. However, if the data processing time has a chance of growing, it is recommended to execute such processing on a separate thread to make sure that the UI remains responsive (and so that you don't get the annoying "Your program is not responding" message from the OS). Basically, if data processing can take longer than ~200ms, it is recommended to execute the processing on a separate thread so that the user doesn't feel like the GUI is "stuck".
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.
I'm working on an application that has a main thread performing some work (message loop of the UI etc.), but I would also like a second thread, which would periodically test if there are any updates available to download. I would also like the possibility for the main thread to ask the secondary thread to force checking for updates, and for the secondary thread to ask the main thread for confirmation on downloading updates.
I don't have that much experience with IPC and multithreading in real life situations, so I'm not sure how I should go about designing this. I would like to eventually have this work on both Windows and POSIX, but let us focus on POSIX for now. Here's my idea so far:
Secondary thread pseudocode:
repeat forever:
check_for_updates()
if (are_any_updates()) {
put the list of available updates on some message queue
send signal SIGUSER1 to main thread
wait for response from that message queue
if (response is positive) download_updates()
}
unblock signal SIGUSER1 on secondary thread
Sleep(one hour)
block signal SIGUSER1
if (any_signal_was_received_while_sleeping)
any_signal_was_received_while_sleeping := false
Sleep(one more hour)
SIGUSER1 handler on secondary thread (main thread has requested us to check for updates):
block signal SIGUSER1 (making sure we don't get signal in signal)
any_signal_was_received_while_sleeping := true
check_for_updates()
...
unblock signal SIGUSER1
Basically, main thread uses SIGUSER1 to ask the secondary thread to force checking for updates, while secondary thread uses SIGUSER1 to ask the main thread to look into the message queue for the available updates and to confirm whether they should be downloaded or not.
I'm not sure if this is a good design or if it would even work properly. One of my problems is related to handling SIGUSER1 received in the main thread, because it's a pretty big application and I'm not really sure when is the right time to block and unblock it (I assume it should be somewhere in the message loop).
Any opinion is appreciated, including advice on what IPC features should I use on Windows (maybe RPC instead of signals?). I could completely remove the use of message queue if I settled on threads, but I might consider using processes instead. I'll clearly use threads on Windows, but I'm not sure about POSIX yet.
You should strongly consider using boost::thread to solve your problem. It is far more comprehensible than directly using posix and is cross platform. Take the time to use a better tool and you will end up saving yourself a great deal of effort.
In particular I think you will find that a condition variable would neatly facilitate your simple interaction.
EDIT:
You can do almost anything with the correct use of mutexes and condition variables. Another piece of advice would be to encapsulate your threads inside class objects. This allows you to write functions that act on the thread and it's data. In your case the main thread could have a method like requestUpdateConfirmation(), inside this you can block the calling thread and wait for the main thread to deal with the request before releasing the caller.
Hey I am not sure if this has already been asked that way. (I didn´t find anwsers to this specific questions, at least). But:
I have a program, which - at startup - creates an Login-window in a new UI-Thread.
In this window the user can enter data which has to be verified by an server.
Because the window shall still be responsive to the users actions, it (ofc it´s only a UI-thread) shall not handle the transmission and evaluation in it´s own thread.
I want the UI-thread to delegate this work back to the main thread.
In addition: The main thread (My "client" thread) shall manage all actions that go on, like logging in, handle received messages from the server etc... (not window messages)
But I am not sure of how to do this:
1.) Shall I let the UI-Thread Queue an APC to the main thread (but then the main thread does not know about the stuff going on.
2.) May I better use event objects to be waited on and queues to transmit the data from one thread to another?...
Or are there way better options?
For example: I start the client:
1. The client loads data from a file and does some intialization
The client creates a window in a new thread which handles login data input from the user.
The Window Thread shall notifiy and handle the , that has been entered by the user, over to the client.
The Client shall now pack the data and delegate the sending work to another object (e.g. CSingleConnection) which handles sending the data over a network (of course this does not require a new thread, because it can be handle with Overlapped I/O...
One special receiver thread receives the data from the server and handles it back to the client, which - in turn - evaluates the data.
If the data was correct and some special stuff was received from the server, the main thread shall signal the UI thread to close the window and terminate...
The client then creates a new window, which will handle the chatting-UI
The chatting UI thread and the Client thread shall communicate to handle messages to be sent and received...
(Hope this helps to get what I am trying)...
It all depends on what you are prepared to use. If you are developing with Qt, their signals and slots are just the thing to do such a communication. They also supply a network library, so you could easily omit the receiver thread because their network classes do asynchronous communication and will send a signal when you have data, which means your thread does not need to be blocked in the mean time.
If you don't want to use Qt, boost also supplies thread safe signals and slots, but as far as I understand it their slots will be run in the context of the calling thread...
Anyways, I have used Qt sig and slots with great satisfaction for exactly this purpose. I wholeheartedly agree GUI's shouldn't freeze, ever.
I don´t know wether this is good style or not (anwsering Your own question):
But I think I go with Event Objects and two queues (one for the connection between Client and Connection, and one to communicate Client and UI)...
I have a Qt/C++ application, with the usual GUI thread, and a network thread. The network thread is using an external library, which has its own select() based event loop... so the network thread isn't using Qt's event system.
At the moment, the network thread just emit()s signals when various events occur, such as a successful connection. I think this works okay, as the signals/slots mechanism posts the signals correctly for the GUI thread.
Now, I need for the network thread to be able to call the GUI thread to ask questions. For example, the network thread may require the GUI thread to request put up a dialog, to request a password.
Does anyone know a suitable mechanism for doing this?
My current best idea is to have the network thread wait using a QWaitCondition, after emitting an object (emit passwordRequestedEvent(passwordRequest);. The passwordRequest object would have a handle on the particular QWaitCondition, and so can signal it when a decision has been made..
Is this sort of thing sensible? or is there another option?
Using signals to send messages between threads is fine, if you don't like using the Condition Variable, then you can send signals in both directions in a more-or-less asynchronous manner: this might be a better option if you want to continue processing network stuff while you wait for a reply from the GUI.