Threads sharing data in C++ - c++

I have a GUI thread that needs information from another thread (IO Thread).
IO thread all its doing is fetching information from serial port.
Gui Thread all its doing is reading the fetches info and display them in a table.
I was thinking maybe, the IO thread should put the data in a global struct protected by a mutex and then the GUI thread should read from that struct. Is there a better implementation?
Would the use of a critical section better than a mutex in this case?
Now I know I will get a reply saying why don't you use only the GUI thread to fetch IO data also, so I won't need multithreading. Yes, I know I am just trying to give a simple example to learn best practices :)
Thank you!

One way to do that is let your IO thread post the input data to the GUI. Whenever you receive data on your IO thread you package it in a struct on the heap and post a custom message together with the address of the struct back to the GUI thread. IOW you create the GUI thread and then the IO thread passing the handle of the GUI thread to the IO thread to be used to send data back to the GUI. That way you do not need to care of about mutex/critical section but you either use the existing GUI message queue or create your own depending on what environment your project is supposed to run in.

What I suggest is two different instances of the same struct. When your IO thread is ready for the GUI thread to be updated, it grabs a mutex, copies it's struct into that of the GUI thread, unlocks the mutex and notifies the GUI thread that it should read an updated copy of the struct.
As for your critical section, that just refers to the concept of having sections of code that only one can be executing at a time. Mostly because you could otherwise get inconsistent state. The way you create a critical section is by gating it with an lock mutex and an unlock mutex.

Related

Passing Pointers to Data Between Threads With Signal/Slot and Without Concurrent Modification in Qt

I have a worker thread object living in a different thread from my main GUI thread created as in the code at the bottom. I need to pass data between the threads without copying the data since the data is quite large (in this case a tree for use in a QAbstractItemModel so don't know how I'd copy it anyways...) and thus will pass a pointer to the data. This will be done using signals and slots. If the main GUI thread and the worker thread only ever process the data during their turn, do I need synchronization primitives/mutexes?
So the logic flow is like this. The worker threads constructs the data, then passes control to the GUI thread with a signal/slot connection. After this signal/slot connection the worker thread no longer does anything with the data. Control lies exclusively in the main GUI thread. Once the program has to process the data it again passes a pointer to the data to worker thread via signal/slot to be processed. After this signal/slot connection the GUI thread no longer does anything with the data. Considering the threads take their turns and signal/slot connections are thread-safe do I need synchronization primitives/mutexes at all?
workerThread = new QThread(this);
workerThread->start();
worker = new Worker;
worker->moveToThread(workerThread);
The GUI thread is called the master thread in general in the context of QT. This master thread has a living event queue. This queue is thread-safe as a result you do not need any synchronization here. However, you are sharing a common memory field among the threads, including your master and worker threads. Here you need to be careful about the shared data in some cases. Let me clarify it by giving some examples.
First of all, if you are sure that there is only one thread working on the data shared at the same time then you do not need any synchronization at all. In some cases, you may want to handle error cases in both threads. In these cases, you may want to access the shared data directly in either thread. As a result, you will need some locking mechanisms but I do not suggest you this approach.
I think the safest way to deal with this is by using event-driven architecture and I reckon that you are already doing this in your design. Just signal your master thread from one worker thread and do nothing in your worker thread until you get an event from the master thread and vice verse. I assume you have only one worker thread in your system.
Please note that your worker thread has also a living event queue already.
As a conclusion, if you have a clear patter and flow in your design with respect to the shared data process then you will not need any locking mechanism.

Is there a semaphore in Qt that is based on event loops as opposed to thread blocking?

The threadblocking of a semaphore or a mutex often causes program stuttering, and I'd rather have one that was based on QEventLoop, where as that will not halt the thread.
Does this already exist, particularly for a semaphore, or do I need to create my own class to implement this?
Thanks.

C++ waiting for response asynchronously, best design?

I have a program with a main loop which must keep running. Sometimes requests will be made to the network so I defer them to a request making service which spawns another thread. What is the best way to act on the eventual response?
My idea is to set a variable when making the request, protect it by a mutex and have the service thread flip the variable when it is finished, with the response. This means I must continually check the variable in the main loop. Is this the best way?
I'm familiar with async programming in Javascript, but there there is only one thread, so a callback can do all the work safely.
Thank you.
EDIT: I'm using C++ 17.
For a lot of traffic I would use a thread to perform the networking, use an "IPC" object containing a mutex, deque and condition-variable.
Use a std::shared_ptr to share the IPC to both main and thread contexts.
When the thread receives the message, it will lock the mutex (use std::lock_guard) and push the message to the deque. Outside the lock, then signal the condition-variable.
The main thread would wait on the condition-variable, when signalled it will then lock the mutex and pop anything from the deque. Note that you use the mutex to protect only the deque.
.
Another approach would be to use a std::async method to receive the message and the main program would wait on it with the get method which will wait until the async method completes.
I'd put the choice largely down to how much networking you are intending to do; if only an occasional "open-send-receive-close" transaction then certainly look at using async.

How to avoid this deadlock between a critical section and SendMessage?

I am fixing a bug in code, and scratching my head at the best way to solve it. Here is how this deadlock occurs:
Worker thread acquires a resource lock.
GUI thread tries to acquire the same resource lock, and blocks.
Worker thread uses SendMessage to the GUI thread, and thus blocks.
The resource being locked is a big data structure about network status - including a list of users, their profile info, etc.
Avoiding the SendMessage call is not realistic, unfortunately. It's too much impact on the program change to something asynchronous to the GUI here.
My instinct is that I should aim to avoid locks in the GUI thread. The GUI thread only needs read access to the data it's locking. This would solve this deadlock, and would probably fix other response time problems in the app. Is this a good instinct?
To do this, I feel the GUI should work with a copy of the data it needs to access, avoiding the need to lock anything at all.
So, how do I get this copy? If I create the copy from the GUI thread, then I must use a lock again, and I haven't solved anything. But how else can I do this?
Or....... is my approach entirely wrong? What is the best way to fix this bug?
Edit: found a similar question: EnterCriticalSection Deadlock
Some possible solutions:
Don't use blocking GUI calls from worker threads -- use PostMessage instead.
If the GUI code that acquires the lock is triggered by a worker, then copy the resource from the worker, and pass the heap pointer to the GUI. This way the GUI doesn't need to lock anything. This is the case for my code, so I will try this.
Use TryEnterCriticalSection in the GUI, and if I couldn't enter, then resume message pumping and just schedule another try later, maybe with PostMessage.
Remove locks around calls to SendMessage in workers.
Using PostMessage instead of SendMessage will avoid the deadlock. There are two ways you could do that. If you do not want to copy the data then the GUI thread message handler will have to acquire the lock to access the data. So there will be contention, but no deadlock. To avoid all contention you would have to make a copy of the data in the worker thread. Use 'new' to put the copy in the heap. Then pass the heap pointer as a parameter of the PostMessage call. The GUI thread can access the data copy, then it should delete the passed pointer.
What kind of operation is the lock guarding on the GUI side? If it's only for something like displaying, it would probably not matter if the operation was done a few dozen milliseconds later.
So could only try to acquire the mutex (e.g. TryEnterCriticalSection()) instead of waiting for it, and if it is not available, reschedule the update later (invalidate the window again to trigger another paint message, queue a custom update message or whatever).

What is the best way to create suspendable/resumable threads

I am doing some network programming for a microprocessor which sends low buffer notifications and I have a thread that writes a set amount of information. When it is done it needs to enter a suspended state and wait for the low buffer notification to resume.
Is it better to use windows' thread pool api, or to use threads that are created with CreateThread()?
When your thread needs to wait, it should begin waiting on an event. This suspends the thread automatically.
Windows provides the WaitForMultipleObjects and WaitForSingleObject functions for this. Linux uses condition variables or semaphores.
The best way to create a suspendable thread is:
std::thread thread(function, arguments);
When you want to suspend the execution of that thread at a later stage you can use the wait() member of std::condition_variable or std::condition_variable_any.
It is better to use single threads created with CreateThread. ThreadPool threads are meant to do simple tasks and then return to the pool, they are not meant for long running tasks, waits or I/O operations. This is because they are limited in number and once you have one running and waiting, you cannot use it somewhere else.
Furthermore, ThreadPool threads are managed by the system and are not meant to be identifiable from the outside. You're better off using classic Threads.