Please nominate your Qt Champions for 2021!

Signaling all threads

  • I'm looking for a way to emit a signal that will be heard by all the threads of a certain type. Basically, I have code where when one thread emits a signal, the only thread of that type that doesn't need to listen to it is the thread that emitted it. Is there any way of doing this? I tried using @connect(this, SIGNAL(mySignal()),threadType,SLOT(mySignalHandler()));@
    but obviously this was a syntax error.

    I've toyed with the idea of consistently polling a shared variable, but I don't want to waste so much of the CPU. I can see that infinite loop in each thread only causing rampant CPU usage. Is there a way to implement this with a timer? I've never used a timer before.


  • I should probably say, when the signal goes, it tells all the threads to check on a shared buffer between them for new data that pertains to them. If they discover data with their ID, then they send this data over their TCP socket. I'm explaining this because I tried to use the QTimer class to have a timer signal that the thread should check the data buffer for data, but when it finds data and then tries to send it, I get a "QSocketNotifier: socket notifiers cannot be enabled from another thread"

    I do not understand what this means. Does it mean that the socket of one thread cannot send data that was brought in from another thread? Or does this mean that the timer (which I think is technically a thread) cannot initiate a signal that will cause the socket to send data?

  • Just in case anyone wondered what the answer was:

    QSocketNotifier prevents threads other than the thread to which the socket belongs to initiate a signal that will cause the socket to write (and I'd assume read, but I haven't seen any evidence of this). To get around it, I added a new slot and signal. The timer called the slot, which emitted the new signal. This new signal called the write slot and to QSocketNotifier it appears that the signal that initiated the write was a signal that was produced by the thread that owns the socket. Problem dodged.

  • Another possible solution without a timer and using signal slots could be that you connect all your threads to the signal (like in your first post). Of course all threads get that signal and as I understood you want all threads except for the one that emit the signal to handle it.
    Easiest solution would be to check in the connected slot if the sender is equal to the receiver.
    if(!sender() == this)
    //handle signal

    For more information on this see "QObject::sender()":

Log in to reply