For the Gtkmm application I'm making, when a row in a ListBoxRow is selected, the callback needs to start a while-loop which will run indefinitely. Let's say the while-loop ends when a particular variable is set to false.
The problem with this, is that my current handler (when it starts the while-loop) completely blocks the main thread, hence blocking any interaction with the GUI.
I think I can use threads to solve this (e.g. start a new thread from the handler, and start the while-loop in the thread), but I foresee problems with this such as:
Multiple threads will be able to be created (by selecting more than 1 row, not at the same time but while another thread is running), so how will I store these threads?
If I store the threads in a vector object, how will I know which thread to join to the main thread, and when to join it?
I'm thinking this must be a fairly common problem, so does Gtkmm or anything else provide a method of perhaps running the handler as a non-blocking function, or something to that effect?
Related
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.
I'm struggling with the idea of background threads in C++.
When I start my application, a thread begins operating in the background for a while. When it is finished, I need to display a message box (whose content depends on the thread's result) and call a function, both on the main thread. While the background thread is running, the application must remain responsive to the user.
I looked at std::future, but that still requires me to either block the main thread or to have some sort of loop running in the main thread that checks the result periodically. But this loop would also have to run asynchronously, leading to the same issue again.
Can someone enlighten me?
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".
I have a function that process frames of video frame by frame and it's quite long. So I decided to put something like Pause and Resume button but I don't know how to end a running function using button. I guessed that it have to do something with thread but I don't know how to do it. Can you give me some advice?
(Note: I'm naming your function ProcessFramesOfVideo() just to make it easier to refer to below)
If the ProcessFramesOfVideo() function is running in your main thread, then most likely your GUI gets frozen up while the function runs, because the GUI event loop won't run until ProcessFramesOfVideo returns.
If that's the case, then the quick-and-dirty way to un-freeze your GUI while ProcessFramesOfVideo() is running would be to call qApp->processEvents() periodically (e.g. once every 50mS or something) from within your loop inside ProcessFramesOfVideo(). That would allow Qt to handle incoming GUI events (like mouse clicks) in a reasonably timely manner while the video is being processed, so that e.g. if the user resizes the window while video is being processed, the widgets resize as expected. Once you have that working, then it's just a matter of putting your Pause and Resume buttons in the GUI as usual, and maybe have them set a "please_stop_processing" boolean flag that also gets checked periodically by ProcessFramesOfVideo()'s loop; if the flag is true, ProcessFramesOfVideo() could return early, or etc.
If you are looking for a more elegant solution than that, the other option would be to spawn a QThread and run the ProcessFramesOfVideo() method in that separate thread. That would allow ProcessFramesOfVideo() to run truly in parallel with the Qt GUI event loop (especially on a multicore CPU), so that GUI responsiveness would not be reduced at all. ProcessFramesOfVideo() could still use the old periodic-check-of-a-boolean technique to know if it should pause or resume its processing; but since you'd have multiple threads involved you'd want to the GUI thread lock a mutex before writing to the boolean, and unlock the mutex afterwards, and you'd want to have the ProcessFramesOfVideo() function lock that same mutex before reading the boolean, and unlock the mutex afterwards. That would ensure that the CPUs' caches and/or compiler optimizations do not interfere with the threads "seeing" each others changes to the boolean flag.
I'm somewhat confused and wondering if I've been misinformed, in a separate post I was told "New threads are only created when you make them explicitly. C++ programs are by default single threaded." When I open my program that doesn't explicitly create new threads in ollydbg I noticed multiple times that there are often 2 threads running. I wanted to understand how the message loop works without stopping up execution, the explanation I got was very insufficient at explaining how it works.
Does the message loop create a new thread or does it take up the main thread? If it takes the main thread does it do so after everything else has been executed regardless of code order? If it doesn't do this but still takes up the main thread does it spawn a new thread so that the program can execute instead of getting stuck in the message loop?
EDIT: Solved most of my questions with experimentation. The message loop occupies the main thread and any code after the code:
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
Will not execute unless something special is done to cause it to execute because the program is stuck in the message loop. Putting an infinite loop in a window procedure that gets executed causes the program to crash. I still don't understand the mystery of the multiple threads when in olly to the degree I would prefer though.
Perhaps the place to start is to realize that "the message loop" isn't a thing as such; it's really just something that a thread does.
Threads in windows generally fall into one of two categories: those that own UI, and those that do background work (eg network operations).
A simple UI app typically has just one thread, which is a UI thread. For the UI to work, the thread needs to wait until there's some input to handle (mouse click, keyboard input, etc), handle the input (eg. update the state and redraw the window), and then go back to waiting for more input. This whole act of "wait for input, process it, repeat" is the message loop. (Also worth mentioning at this stage is the message queue: each thread has its own input queue which stores up the input messages for a thread; and the act of a thread "waiting for input" is really about checking if there's anything in the queue, and if not, waiting till there is.) In win32 speak, if a thread is actively processing input this way, it's also said to be "pumping messages".
A typical simple windows app's mainline code will first do basic initialization, create the main window, and then do the wait-for-input-and-process-it message loop. It does this usually until the user closes the main window, at which point the thread exits the loop, and carries on executing the code that comes afterwards, which is usually cleanup code.
A common architecture in windows apps is to have a main UI thread - usually this is the main thread - and it creates and owns all the UI, and has a message loop that dispatches messages for all of the UI that the thread created. If an app needs to do something that could potentially block, such as reading from a socket, a worker thread is often used for that purpose: you don't want the UI thread to block (eg. while waiting for input from a socket), as it wouldn't be processing input during that time and the UI would end up being unresponsive.
You could write an app that had more than one UI thread in it - and each thread that creates windows would then need its own message loop - but it's a fairly advanced technique and not all that useful for most basic apps.
The other threads you are seeing are likely some sort of helper threads that are created by Windows to do background tasks; and for the most part, you can ignore them. If you initialize COM, for example, windows may end up creating a worker thread to manage some COM internal stuff, and it may also create some invisible HWNDs too.
Typically the thread that starts the program only runs the message loop, taking up the main thread. Anything not part of handling messages or updating the UI is typically done by other threads. The additional thread that you see even if your application doesn't create any threads could be created by a library or the operating system. Windows will create threads inside your process to handle things like dispatching events to your message loop.