Communication among threads in Qt - qt

I'm working with threads in C++/Qt, each one to establish and mantain a QTcpSocket connection.
The problem is that when a disconnection from network comes, those threads must reconnect in a certain order. That's already working, but I have another problem: I need to know into each thread if only current thread has been disconnected, or all of them have been disconnected.
The first idea I had was to pass every thread a reference to a class where I would be able to store each thread status and check everyone else's.
But then I had an easier idea, and I would like to know if it would work or if it impossible: use Qt's slots and signals.
So, every thread I have comes from the same class, but passing different data to the Ctor. So the idea would be to create a slot and a signal inside that class, connect them and emit the signal passing an ID. Then, every thread's slot would be launched... or I may be completely wrong and the only slot launched would be the one from the very same thread which emited the signal.
Is this possible or not?

First of all, signal-slot connections are done between signals and slots in QObjects, not between threads. Well, a QThread is a QObject, but you really should not derive from a QThread. Do not derive from QThread and you'll be fine.
What you do is:
Get one or more QThreads started (not merely constructed). Those QThreads are just the base Qt classes, don't derive from them. A started raw QThread is blocked, waiting for an event to be posted to its event queue. The default implementation of QThread::run() calls QEventLoop::exec() (or an equivalent). Thus those threads, after starting, don't consume any CPU cycles.
Instantiate a bunch of QObjects. Do all the signal/slot connections as necessary.
Move those objects to one or more QThreads by calling moveToThread(QThread*) on them.
As you see, setting up signal slot connections is done in the usual manner and does not require any special attention. Qt does everything for you, including changing connection types from Qt::DirectConnection to Qt::QueuedConnection when you move the QObjects between threads.
Note that you must not call any methods on those QObjects directly, because you'll be doing so likely from a different thread, so all sorts of bad things will happen as the access is not serialized. You must do any of the below, and only that, in order from fastest to slowest. Note that while #3 is always faster than #4, you need to benchmark between #2 and #3 as it varies.
Post a custom event to the QObject, and handle it in the derived QObject's customEvent(QEvent*) method.
Use the signal-slot connections, and emit signals that got connected to the QObjects' slots.
Use QMetaMethod::invoke on a previously looked up method. The is faster than #4 since the method lookup is done only once in advance.
Use QMetaObject::invokeMethod.
Posting QEvents to QObjects is faster than using signal-slot invocations, because there are no copy constructors called and there's no marshalling done except directly by you upon construction of a QEvent.
Only if profiling/benchmarking shows that event posting is too slow you'd want to look at using QSharedMemory. Having an excessive number of QThreads is counterproductive, you should have probably not more than the number of CPU cores on the system. Using synchronization primitives such as mutexes or semaphores naively requires you to commit way too many threads. You definitely do not want to have one thread per connection! Qt already has an event queue mutex for each QObject, by using the event queue you already use that.

Signal and slot connections are done in run time, i.e. you are connecting specific instances of a class. You cannot emit a signal and "broadcast" it to every instance of your class. Signals between different threads is possible, but maintaining them could be a bit of a hassle (It's all explained pretty well in the documentation).
If I were you, I'd probably look into QSemaphore or QSharedMemory.

Related

Qt QTcpSocket waitForReadyRead crashes when socket is closed from a different thread

I am calling waitForReadyRead method of QTcpSocket in a separate thread(pthread) ,
Now if socket is closed from the main thread the application crashes in waitForReadyRead method.
And I am using waitForReadyRead with time out = -1.
Also I cannot use qt signal slot mechanism in my implementation
Can someone Please explain me what is wrong in the above implementation
From the Qt documentation of QTcpThread:
Note: All functions in this class are reentrant.
This means that it is not safe to call one object from multiple threads (read this for more info). Even if you get your code to work somehow it might crash in an older or newer version.
If you really can't use signals/slots then you could set a flag when you want to close the connection and call waitForReadyRead in a loop with a timeout. Then you can poll the flag and close the socket with the waitForReadyRead-thread if it is set.

Sharing data across Qt threads

I'm new to Qt so please excuse the simplicity of the question but I'm a bit confused on the Qt threading. Let's say I have 3 threads: the main default GUI thread, and 2 threads of my own creation (called WorkerThread). Each of my WorkerThreads inherits from QThread and are permanent threads that every so often wake up and send data out a socket and post status on a GUI element. How is the best way to 1) allow the GUI thread to set data in the WorkerThread object that the WorkerThread thread can use? 2) allow the WorkerThread to send status to the GUI thread to be displayed for the user? 3) Allow both WorkerThreads to use the same socket?
It seems from the documentation that when I create a WorkerThread object it is owned by the creating thread (except for the run method that is a new thread). So how does one set data for the new thread to execute on? Must all the data the new thread uses be global? For instance, I would like the GUI to allow the user to select a packet type for each of the WorkerThreads to send when they wake up. I had assumed that I would put in some slots in the WorkerThread that the GUI thread would signal. When the WorkerThread object received a signal to SetPacketType it would set a member variable that the run method references on each iteration. But after reading the documentation I'm not sure that is the way to do it. If the WorkerThread object is owned by the creating thread (GUI thread in this case) then sending signals to it doesn't cross thread boundaries does it?
Also, what is the proper technique for sharing the socket connection across threads?
Thanks in advance.
With Qt, the easiest way to send information between threads is to use signals and slots. Qt automatically uses queued signals for connections between threads (see Qt::ConnectionType), which ensures that a signal can be emitted from one thread, but the slot will be executed in the thread of the receiver object.
If the data being sent between threads (work to be done or status information) is something that Qt can automatically queue (e.g., QStrings, built-in types like int and double, and others), then passing the info as the arguments to the signal/slot is the best way to send the info. If large or complex data is being shared, then you either need to use qRegisterMetaType to allow Qt to copy the data, or pass a pointer to a thread-safe object. Unlike what Pie_Jesu said, the threads do share an address space so you can share pointers; just make sure that one thread's interaction with the shared object won't interfere with another thread's interactions.
QTcpSocket is not thread-safe (it's only reentrant according to Qt's documentation), so if you share the socket you will have to be responsible for ensuring that threads don't use the socket in conflicting ways.

Qt Signals and slots

How many signals at maximum you can connect to a single slot? If more than one how you can do that? How many slots can you connect to a signal? If more than one how those slots will be executed? How a Qt Program/Application written for one platform (Symbian) can be ported/executed in another
You can easily connect more than one slot to a single signal using the usual way (QObject::connect), which are then called in order of connection when the signal is emitted.
Likewise can a single slot be connected to multiple signals, which is then called whenever one of those signals is emitted. You can even chain signals by connecting signals to signals, which are then emitted automatically whenever the source signal is emitted.
Such information can easily be gained by Qt's excellent documentation.
There may be a theoretical limit on the number of slots that can be connected to a signal, but this limit is surely beyond any practical relevance.
Although porting an application from an embedded system, like Symbian, to a desktop system, like Windows, may involve some additional issues, in general the porting of a Qt application to another platform just requires recompilation on/for that platform, assuming you didn't use any platform-dependent code in the rest of your application, which is usually not neccessary when using Qt.
you can connect as many slots to a signal as you wish. They will be executed in order in which they were connected.
Generally if you use only qt and no other platform dependent API, then recompiling it on target platform should be enough. Have no idea about Symbian though - sometimes Symbian seems to have a bit different rules.

POSIX Threads: are pthreads_cond_wait() and others systemcalls?

The POSIX standard defines several routines for thread synchronization, based on concepts like mutexes and conditional variables.
my question is now: are these (like e.g. pthreads_cond_init(), pthreads_mutex_init(), pthreads_mutex_lock()... and so on) system calls or just library calls? i know they are included via "pthread.h", but do they finally result in a system call and therefore are implemented in the kernel of the operating system?
On Linux a pthread mutex makes a "futex" system call, but only if the lock is contended. That means that taking a lock no other thread wants is almost free.
In a similar way, sending a condition signal is only expensive when there is someone waiting for it.
So I believe that your answer is that pthread functions are library calls that sometimes result in a system call.
Whenever possible, the library avoids trapping into the kernel for performance reasons. If you already have some code that uses these calls you may want to take a look at the output from running your program with strace to better understand how often it is actually making system calls.
I never looked into all those library call , but as far as I understand they all involve kernel operations as they are supposed to provide synchronisations between process and/or threads at global level - I mean at the OS level.
The kernel need to maintain for a mutex, for instance, a thread list: threads that are currently sleeping, waiting that a locked mutex get released. When the thread that currently lock/owns that mutex invokes the kernel with pthread_mutex_release(), the kernel system call will browse that aforementioned list to get the higher priority thread that is waiting for the mutex release, flag the new mutex owner into the mutex kernel structure, and then will give away the cpu (aka "ontect switch") to the newly owner thread, thus this process will return from the posix library call pthread_mutex_lock().
I only see a cooperation with the kernel when it involves IPC between processes (I am not talking between threads at a single process level). Therefore I expect those library call to invoke the kernel, so.
When you compile a program on Linux that uses pthreads, you have to add -lphtread to the compiler options. by doing this, you tell the linker to link libpthreads. So, on linux, they are calls to a library.

Implementing preemptive microthreads using signal handlers and setjmp/longjmp

I want to implement POSIX compliant microthreads in Linux environment. Basic idea is as follows:
Using technique described here, assign new stack space for each fiber.
Using setitimer, create timer that will send signals in constant time interval. Signal handler for this timer will act as a scheduler and switch between fibers.
The problem is, that doing longjmp in signal handler, won't terminate the handler, so kernel will wait for it's termination, instead for delivering new signals. This makes switching contexts impossible, because there are no signals to initiate the switches.
One solution would be to unblock SIGALRM, so many signals can execute the handler at the same time, but this will cause race conditions problems.
What is the best and simplest way to implement preemptive microthreads ? All examples I found on Google were not preemptive.
The solution is to use sigsetjmp / siglongjmp, intstead of setjmp/longjmp. sig* versions preserve signal masks :)

Resources