About Qt::DirectConnection



  • There is an example in page: https://wiki.qt.io/Threads_Events_QObjects.

    class Thread : public QThread
    {
     Q_OBJECT
     
    slots:
     void aSlot() {
     /* … */
     }
     
    protected:
     void run() {
     QObject *obj = new Object;
     connect(obj, SIGNAL (aSignal()), this, SLOT (aSlot()));
     /* … */
     }
    };
    

    Because it don't give a argument to tell it use which connect method, so Qt will choose the queued version. Then what if we force it to use 'Qt::DirectConnection'? I tried, yes, the aSlot() is called. Then, is it still necessary to use the "good way" the page stated, that is, use another "Worker" class and "moveToThread"?


  • Moderators

    @diverger If you use direct connection then the slot will be executed in your thread which is not necessarily same thread as the class with the slot. This may work or not depending on what you do in the slot (if you access objects/variables located in another thread your app can crash). In general it is better to use queued connection between threads.



  • @jsulm Thanks. I've another question. I'm not famillar with 'moveToThread'. I can't find more docs about it. Assume the code below:

    class Worker : public QObject
    {
     Q_OBJECT
     
    public slots:
    void doOther() {}
     void doWork() {
     /* … */
     }
    };
     
    /* … */
    QThread *thread = new QThread;
    Worker *worker = new Worker;
    connect(obj, SIGNAL (workReady()), worker, SLOT (doWork()));
    worker->moveToThread(thread);
    thread->start();
    doOther();
    

    I add another method 'dOther()' to Worker class. And call it in the main thread. I tried it, the code is executed in the main thread indeed. Then what moveToThread() done, why I can call object's method in the main thread after move the object to a new thread?


  • Moderators

    @diverger Well, you can always call any public method of that object from another thread. But the question is: what will happen? Since you moved the object to another thread, calling a method from main thread can lead to race conditions, but that depends on what you're doing in that method.



  • @jsulm You mean call other thread's object methods is llegal in Qt?



  • First: If you don't specify the connection type the default is Qt::AutoConnection which means that Qt decides which type is appropriate.
    DirectConnection means that the slot is called immediately, QueuedConnection means that the slot is called indirectly from the event queue.

    Every object knows in which thread it was created and where it "lives" (which can be influenced using the moveToThread() method). So a cross thread connection is queued by default to be threadsafe (that's one benefit of the event queue). You can also use the direct connection for cross thread calls, it's not illegal - but then it's up to you to ensure that this call is threadsafe! You have to handle locking and sychronisation (depending on what's done in your slot). If you use the queued connection you don't have to think about it (in most cases).
    See also http://doc.qt.io/qt-5/threads-qobject.html


  • Moderators

    @diverger As @micland already explained this does not have anything to do with Qt. It is a general problem with multi-threading: if you call a method from an object which leaves in another thread then you have to make sure this does not cause any problems.


Log in to reply
 

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