Solved 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? -
@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 onethis
resides in. -
It is happening due to Qt::DirectConnection. Y do u need Qt::DirectConnection. Use it if required really.
-
@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 toQt::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. -
@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. -
@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.
-
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(...)
-
@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 toDirectConnection
anyway (see below case 2 for when it's relevant).So there are 2 options to have the slots executed in different threads:
- Between emission of the
readyRead
signal and thepushclient
signal the thread was changed by a call tomoveToThread
. - The
pushclient
signal was called directly (as a method) from a thread that is different from the threadthis
is assigned to.
- Between emission of the
-
@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(). -
@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 .