Signals/slots accross threads



  • Hello all !

    I have some difficulties to find an appropriate way to solve a problem of communication between objects in differents threads (although I already read the Signals/slots accross threads). Here is my problem:

    I have an object a of class A living in a thread T1.
    I have an object b of class B living in a thread T2.

    Both objects a and b can emit signals and have slots to manage the signals emitted by the object living in the other thread (Object a has slots to manage signals from object b, and object b have slots to manage signals from object a).

    Once I have moved the object to their respective threads, I connect the signals/slots using Qt::connect(..., Qt::QueuedConnection), but once the signals is emitted, the slot is never executed.

    I don't use Qt::DirectConnection (because it's quite the same that invoking directly the method, and I don't want this), and I would like to avoid to manage an event dispatcher or an event loop in the parent thread.

    Does someone know how to use correctly the Qt threads in order to make the communication between signals/slots between objects living in different threads (none living in the main thread) ?

    Thank you a lot for your answers !


  • Qt Champions 2016

    @mistralegna
    Hello,

    I don't use Qt::DirectConnection (because it's quite the same that invoking directly the method, and I don't want this), and I would like to avoid to manage an event dispatcher or an event loop in the parent thread.

    Just use the default Qt::AutoConnection (which expands to Qt::QueuedConnection when the objects are in different threads). Now to the core of the problem, you can't have objects' slots invoked when there's no event loop running in the thread the object is residing in. So if you've reimplemented QThread::run, which is my suspicion, you won't be able to have slots executed in that thread.
    When a signal is emitted and there's a slot connected to that signal an event is posted in the receiving thread's event loop that the slot should be invoked. Consequently, when the event is processed the slot will be invoked. So you can see that without event loop there's no slots!

    Kind regards.


  • Qt Champions 2016

    @mistralegna
    Well, I forgot, but in case you want to make your code work with an event loop and signal-slot connections you can look here how QThread should ordinarily be used.



  • Thank you for your answer !

    Just to be sure, in this ultimate case (the link you're refering to), is it correct to make a direct connection, although the Qt::AutoConnection works fine ?

    Thank you !

    @mistralegna said:

    Hello all !

    I have some difficulties to find an appropriate way to solve a problem of communication between objects in differents threads (although I already read the Signals/slots accross threads). Here is my problem:

    I have an object a of class A living in a thread T1.
    I have an object b of class B living in a thread T2.

    Both objects a and b can emit signals and have slots to manage the signals emitted by the object living in the other thread (Object a has slots to manage signals from object b, and object b have slots to manage signals from object a).

    Once I have moved the object to their respective threads, I connect the signals/slots using Qt::connect(..., Qt::QueuedConnection), but once the signals is emitted, the slot is never executed.

    I don't use Qt::DirectConnection (because it's quite the same that invoking directly the method, and I don't want this), and I would like to avoid to manage an event dispatcher or an event loop in the parent thread.

    Does someone know how to use correctly the Qt threads in order to make the communication between signals/slots between objects living in different threads (none living in the main thread) ?

    Thank you a lot for your answers !


  • Qt Champions 2016

    @mistralegna said:

    Just to be sure, in this ultimate case (the link you're refering to), is it correct to make a direct connection, although the Qt::AutoConnection works fine

    Short answer: No.
    Long answer:

    • Qt::DirectConnection forces Qt to invoke the receiving slot/signal directly, and it doesn't care about threads, so it's not thread safe.
    • Qt::QueuedConnection forces Qt to "delay" invocation of the receiving signal/slot by posting an event in the event queue of the thread the receiving object resides in. When the signal/slot is actually executed it is done in the receiver object's thread.
    • Qt::AutoConnection (the default parameter) is a bit smarter. When a signal is emitted Qt checks the connection type, if it's an auto connection it checks the sender and receiver's thread affinity (the threads they live in).
      1. If the threads are different, it posts an event for the receiver object's thread (works as a queued connection)
      2. If on the other hand the threads are one and the same it directly invokes the signal/slot.

    In conclusion, if you're not doing something specific, just leave the connection parameter out and use the default auto connection.



  • Thanks, it's exactly the answer I was waiting for. It was Just to be sure indeed it was not thread safe to use such a direct connection.

    Thank you a lot for your answers!


  • Qt Champions 2016

    @mistralegna

    Thanks, it's exactly the answer I was waiting for.

    I'm glad. :D

    Thank you a lot for your answers!

    You're welcome.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.