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

signal and slots in movetothread



  • IF there are two connections define in workerclass :
    connect(m_socket,SIGNAL(readyRead()),this,SLOT(readData()));
    connect(this,SIGNAL(pushclient(QTcpSocket*,qintptr)),this,SLOT(clientList(QTcpSocket*,qintptr)),Qt::DirectConnection);

    Both slots are defined in worker thread.but readData() is executing in new thread(worker thread) while clientlist() is executing in main thread.
    how it is possible?


  • Qt Champions 2017

    @JadeN001 said in signal and slots in movetothread:

    Both slots are defined in worker thread

    This makes no sense. Slots, and functions or methods, are not assigned to any thread. A thread, in simple terms, is a function that is the root of the call stack and any function can be called from one thread or another. The function can't know beforehand what thread it will be called from, as it's up to you to actually call it.

    but readData() is executing in new thread(worker thread) while clientlist() is executing in main thread.
    how it is possible?

    You have changed the thread affinity between the two calls or you have called the pushclient signal directly from your code from thread different than the one this resides in.


  • Qt Champions 2017

    It is happening due to Qt::DirectConnection. Y do u need Qt::DirectConnection. Use it if required really.


  • Qt Champions 2017

    @dheerendra said in signal and slots in movetothread:

    It is happening due to Qt::DirectConnection.

    I disagree. Sender and receiver being the same Qt::AutoConnection defaults to Qt::DirectConnection anyway.



  • @dheerendra Because i am passing qintptr as argument to signal and slots so i have to do directconnection.If i dont,i am getting qregistry type of error.



  • @kshegunov Sorry its my mistake about "Both slots are defined in worker thread"
    it is "both slots are defined in worker class".A class whose object is moved to thread.

    " You have changed the thread affinity between the two calls or you have called the pushclient signal directly from your code from thread different than the one this resides in."
    I don't understand what it means.


  • Qt Champions 2017

    @kshegunov @JadeN001 When I looked at the question, readData() & clientList() are defined in worker class(assuming that 'this' refers to workerclass). It all depends on where the object 'this' is created. Since readData() is executed() in workthread and it means to me that 'this' ClientList() context is also in workthread.

    SLOT can get executed in main thread only if 'this' object is in main thread or you have directConnection. It should be either of this case only.



  • @dheerendra As i have understand from the documentation is that In Directconnection,
    slot will execute on thread of the signal's object.that is in my case thread of worker object.


  • Moderators

    @JadeN001 said in signal and slots in movetothread:

    @dheerendra Because i am passing qintptr as argument to signal and slots so i have to do directconnection.If i dont,i am getting qregistry type of error.

    Actually, a q_register_type /metatype error is an indicator, that receiver and sender do not live in the same thread.

    registering types does not matter much, by direct connections, but Qt::AutoConnection defaults to 'Qt::QueuedConnection' when crossing threads, and then the meta system needs to know the types.

    By forcing direct connection here, without mutexes, you're bound to run in memory access violations.


  • Qt Champions 2017

    only chance now is that 'this' is under the control of main thread. Can you use QObject::thread() method and check which thread owns it ? You can check this before emitting the signal pushclient(...)


  • Qt Champions 2017

    @dheerendra @JadeN001 @J.Hilk
    This slot:

    connect(m_socket,SIGNAL(readyRead()),this,SLOT(readData()));
    

    will be called in this's thread (whatever the class is).

    This slot:

    connect(this,SIGNAL(pushclient(QTcpSocket*,qintptr)),this,SLOT(clientList(QTcpSocket*,qintptr)),Qt::DirectConnection);
    

    will also be called in this's thread. The connection type has little relevance to normal code, as the emitter and receiver are one and the same and the default expands to DirectConnection anyway (see below case 2 for when it's relevant).

    So there are 2 options to have the slots executed in different threads:

    1. Between emission of the readyRead signal and the pushclient signal the thread was changed by a call to moveToThread.
    2. The pushclient signal was called directly (as a method) from a thread that is different from the thread this is assigned to.

  • Qt Champions 2017

    @kshegunov agree with you. Options mentioned by you are the only choices. Hence I mentioned that he can check QObject::thread() find out if the object is moved in between.



  • @dheerendra yes i have checked using QThread::Currentthread() in clientlist() solt and as a result this slot is executing in main thread but readData() is executing on new thread from Qthreadpool.
    my short question is how can is execute clientlist() in same thread readData() is executed.



  • @kshegunov as i know slot will execute on thread where sender's object is created in directconnection senario.here m_socket is created in class of worker.and this
    of signal(pushclient) `is created in myserver class.
    Atually these two connect are in myworker.cpp .so this object of both signal and slot are actually worker object which i have created in myserver.cpp as a:
    myworker *worker=new myworker();
    worker->moveToThread(mythread);

    so,i think problem is that clientlist() slot is executing in mainthread.Because this object of signal pushclient is created in myserver.cpp(threads of myserver.cpp and clientlist slot are same)
    readData() is running in thread of pool thread because m_socket is created in worker class.am i right?if so,how can i execute clientlist() in same thread as readData().


  • Qt Champions 2019

    @JadeN001 said in signal and slots in movetothread:

    as i know slot will execute on thread where receiver's object is created in directconnection senario

    As far as I know this is completely wrong. This is only the case with queued connection. Direct connection will mean that the slot is executed in the thread where the signal is emitted.



  • @jsulm yes you are right it is my mistake. it should be sender instead of receiver.



  • hey my problem is solved i have to just remove Qt::directconnection from the 2nd connect().thanks to all for helping me .


Log in to reply