Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Order of slots execution



  • Will slots be executed in the same order in which their corresponding signals were emitted?
    If a QObject emit signal A and then immediately signal B, can I assume that the slot connected to signal A will be executed before the slot connected to signal B?

    connect(objectA, SIGNAL(signalA(int)), objectB, SLOT(slotA(int)))
    connect(objectA, SIGNAL(signalB(int)), objectB, SLOT(slotB(int)))
    

    somewhere in objectA's code:

    void objectA::signalsEmitter() {
       ...
        emit signalA(x);
        emit signalB(y);
       ...
    }
    

    in objectB's code:

    void objectB::slotA(int x) {
        // Will that be executed before objectB::slotB?
        ...
        ...
    }
    
    void objectB::slotB(int x) {
        ...
        ...
    }
    

  • Moderators

    @Absurd said in Order of slots execution:

    If a QObject emit signal A and then immediately signal B, can I assume that the slot connected to signal A will be executed before the slot connected to signal B?

    If the senders and receivers all live in the same thread, then it's quite safe to assume that.

    However, relying on a particular order can be error-prone. Could you merge both slots into one function instead?



  • @JKSH said in Order of slots execution:

    Could you merge both slots into one function instead?

    I probably can.
    Just thought it'll be easier/more readable/modular that way...

    Thanks!



  • @Absurd said in Order of slots execution:

    Just thought it'll be easier/more readable/modular that way...

    Yes, it will but as mentioned previously relying on execution order is not a good approach, and it might also indicate that the two methods are indeed very likely to be just one?



  • In general I also think it is better to program with signals and slots in an asynchronous method, that is to say never write code that assumes signals/slots are emitted / executed in a specific order. Instead if you need slots to run in a specific order then they should call their chain slots with a signal of their own or return a signal back to the original caller so that it knows it can then emit the next signal to trigger the next slot.


  • Lifetime Qt Champion

    Hi,

    @Absurd said in Order of slots execution:

    @JKSH said in Order of slots execution:

    Could you merge both slots into one function instead?

    I probably can.
    Just thought it'll be easier/more readable/modular that way...

    Thanks!

    How are these slots related to each other ?
    Are they reused somewhere else ?
    How did you split the code ?



  • Thanks for anyone who tried to help.
    I decided to go with one signal and one slot. I merge the two slots into one.



  • Follow up question:
    Do slots-that-invoked-due-to-signal run synchronously to main-thread of execution?

    For example, in my code example above:
    Am I guaranteed that slotA() will be executed only after signalsEmitter() has finished execution?

    (reason I'm asking is that I experience some weird behavior, which I think is a result of some race...)

    Thanks.


  • Moderators

    @Absurd said in Order of slots execution:

    Do slots-that-invoked-due-to-signal run synchronously to main-thread of execution?

    For example, in my code example above:
    Am I guaranteed that slotA() will be executed only after signalsEmitter() has finished execution?

    No.

    If the sender and receiver live in the same thread, then you will have a Qt::DirectConnection by default. In this scenario, Emitting a signal is the same as calling all connected slots. This means the signal emission blocks until all the slots have finished executing.

    So in your example above, the order of execution is like this:

    void objectA::signalsEmitter() {
       ...
        // emit signalA(x);
        objectB->slotA(x);
    
        // emit signalB(y);
        objectB->slotB(y);
       ...
    }
    

    signalsEmitter() returns AFTER your slots have finished executing.


  • Lifetime Qt Champion

    @Absurd,

    no that assumption is not guaranteed.

    If both objects are in the same thread, the slot is run immediately on emit (like a functoin call).

    Otherwise, it will run anytime after emit.



  • @JKSH , @aha_1980
    Just to make sure I understand... (and sorry if it sounds like a stupid question, as I don't have any experience with multi-threading programs...)
    Although a single object can be instantiated by only one thread, it can be accessed by many, so what's the meaning behind "objects that live in the same thread"?


  • Lifetime Qt Champion

    @Absurd it's meant, if your objects are both in the same or in different threads.

    Accessing objects from different threads is ... complicated. but with signals and slots its super-easy.


  • Moderators

    @Absurd said in Order of slots execution:

    what's the meaning behind "objects that live in the same thread"?

    This concept applies to QObjects and the signal-slot mechanism. In simple terms, when we say that a QObject lives in Thread X, we mean that the QObject's slots will run in Thread X.

    If your program is single-threaded, then you don't need to worry about this concept. If you want to learn more, read http://doc.qt.io/qt-5/qobject.html#thread-affinity.

    Although a single object can be instantiated by only one thread, it can be accessed by many,

    That is technically true, but there are dangers in allowing an object to be accessed from multiple threads. You'll need to take extra steps to make your object thread-safe.

    Just to make sure I understand... (and sorry if it sounds like a stupid question, as I don't have any experience with multi-threading programs...)

    It's a perfectly valid question :) We all ask questions to deepen our understanding! We're happy to answer your questions.


Log in to reply