QThread inheritance then invoking.
-
Hello i am trying to make a multithreaded socket server, i want so that when i press a button in the gui it sends some data to the client.
When i click the button i invoke the send methoed in the socket thread the issue i get the following error:QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
The data is still sent but it takes a long time todo so i.e sending 300 bytes takes around 1 minute.
When calling it directly from the thread in the run methoed it takes less than a second.
I know this is something todo with the threads, as when i print the current thread in the send methoed.
I am in QThread(0x2458ceea480) but the QSocket->currentthread() is
SocketThread(0x24592218ac0).
So how do i make the QSocket->currentthread() call write? -
@raketmus
Your sockets must live in the thread where you do operations on it. If you create the socket in the main thread you canmoveToThread()
if you will use it in another thread.I see you are new-ish, and have posted questions about
QThreads
previously. It is possible that you genuinely need threads, but more than half the time newcomers seem to do so they are unnecessary. Qt sockets are asynchronous by nature, so make sure you really need separate threads and can't do its work off the main thread, to save yourself potential grief. -
@raketmus said in QThread inhertance then invoking.:
So how do i make the QSocket->currentthread() call write?
Create your socket in the thread where you want to read/write. See QTcpServer::incomingConnection()
-
@Christian-Ehrlicher said in QThread inhertance then invoking.:
@raketmus said in QThread inhertance then invoking.:
So how do i make the QSocket->currentthread() call write?
Create your socket in the thread where you want to read/write. See QTcpServer::incomingConnection()
Well issue if i did that after lets say 20 clients my whole gui would be come almost unusable.
Do to everything running in one thread thats why on QTcpServer::incomingConnection() i create a new thread and make that thread the owner then i transfer the socket to it.@JonB said in QThread inhertance then invoking.:
@raketmus
Your sockets must live in the thread where you do operations on it. If you create the socket in the main thread you canmoveToThread()
if you will use it in another thread.I see you are new-ish, and have posted questions about
QThreads
previously. It is possible that you genuinely need threads, but more than half the time newcomers seem to do so they are unnecessary. Qt sockets are asynchronous by nature, so make sure you really need separate threads and can't do its work off the main thread, to save yourself potential grief.- But i need the read opreations to happen in the thread do i just transer the ownership in the send fuction.
Is moveToThread() not a very expensive operation?
Is there not a way in which much like inQMetaObject::InvokeMethoed()
i can invoke the methoed to be called from the context of the socket thread?
I thought that was what invoke methoed was doing but aperently not. - Well as i said above i do really need multithreading if not it would lag which i could not use.
- But i need the read opreations to happen in the thread do i just transer the ownership in the send fuction.
-
There is a good example on how to do threading with QTcpSockets - follow that.
-
@Christian-Ehrlicher said in QThread inhertance then invoking.:
There is a good example on how to do threading with QTcpSockets - follow that.
I have done so but this example features no calling from the gui thread to the other thread i.e no interactivitie all is done in the thread.
-
To pass data between threads in Qt the safest way is to use Signals and Slots
-
@Christian-Ehrlicher said in QThread inhertance then invoking.:
To pass data between threads in Qt the safest way is to use Signals and Slots
But this still gets called from my gui thread as the context and not SocketThread.
How do i make the send methoed get called from SocketThread? -
@raketmus said in QThread inhertance then invoking.:
But this still gets called from my gui thread as the context and not SocketThread.
You have to trigger something in the gui thread, yes.
And Qt sockets are async - no need to use threads at all.
-
@Christian-Ehrlicher said in QThread inhertance then invoking.:
@raketmus said in QThread inhertance then invoking.:
But this still gets called from my gui thread as the context and not SocketThread.
You have to trigger something in the gui thread, yes.
And Qt sockets are async - no need to use threads at all.
That does not explain anything and i as i have stated before i need multithreading a single thread simply cannot do.
And my question was how do i call this from socketthread when i click and button in my gui? -
@raketmus said in QThread inhertance then invoking.:
i need multithreading a single thread simply cannot do
It can, Qt sockets are asynchronous - they do NOT block the thread.
"And my question was how do i call this from socketthread when i click and button in my gui?" - emit a signal when the button is clicked. Connect a slot to that signal in your thread. By default slot is executed in the thread when doing signals/slots between threads (queued connection).
-
@jsulm said in QThread inhertance then invoking.:
@raketmus said in QThread inhertance then invoking.:
i need multithreading a single thread simply cannot do
It can, Qt sockets are asynchronous - they do NOT block the thread.
"And my question was how do i call this from socketthread when i click and button in my gui?" - emit a signal when the button is clicked. Connect a slot to that signal in your thread. By default slot is executed in the thread when doing signals/slots between threads (queued connection).
Well such a system is not very good reading data that is size tagged i.e 4 bytes to int of size then you read that many bytes for a packet.
That would simple not work as that is blocking and i dont know how not make it work like that. -
@raketmus said in QThread inhertance then invoking.:
That would simple not work as that is blocking
What is blocking?
You simply use readyRead signal and read until you got whole package, there is nothing blocking...
I suggest you take a look at Qt networking examples. -
@raketmus
I'm trying to guess what you are saying here.I think you are talking about: you read data sent across a socket. You receive, for example, a "message" which says the next thing is a 4-byte-integer, and then you receive the 4-byte integer. You presently have blocking code which says after receiving the indicator that what follows is 4 bytes, you then block on a "read 4 bytes" call. Is that about right?
Don't do it this way! When bytes arrive (in
readRead()
) append them to a buffer of pending data. Do not block! Then, you inspect the length of the buffer to see whether you have received at least as many bytes as a "message", e.g. the 4 bytes after the "indicator" here. Then you pull out the indicator plus the 4 byte integer, all already received, and process that "message".This is the right way to do things in an asynchronous framework, and avoids any blocking, and need for threads. See also
QDataStream
Using Read Transactions. -
@JonB said in QThread inhertance then invoking.:
@raketmus
I'm trying to guess what you are saying here.I think you are talking about: you read data sent across a socket. You receive, for example, a "message" which says the next thing is a 4-byte-integer, and then you receive the 4-byte integer. You presently have blocking code which says after receiving the indicator that what follows is 4 bytes, you then block on a "read 4 bytes" call. Is that about right?
Don't do it this way! When bytes arrive (in
readRead()
) append them to a buffer of pending data. Do not block! Then, you inspect the length of the buffer to see whether you have received at least as many bytes as a "message", e.g. the 4 bytes after the "indicator" here. Then you pull out the indicator plus the 4 byte integer, all already received, and process that "message".This is the right way to do things in an asynchronous framework, and avoids any blocking, and need for threads. See also
QDataStream
Using Read Transactions.- The issue here is using only 1 thread will cause lag seeing as proccesing data from 20 clients in a single thread and also doing gui will casuse lag.
- I dont want async i want sync becuase my client is sync and i would like to be able to just copy code.
@jsulm said in QThread inhertance then invoking.:
@raketmus said in QThread inhertance then invoking.:
That would simple not work as that is blocking
What is blocking?
You simply use readyRead signal and read until you got whole package, there is nothing blocking...
I suggest you take a look at Qt networking examples.The samples are simpley to basic non of then are able to recive binary.
Becuase when sending and reciveing binary you have to send how long the data is gonna be. -
@raketmus said in QThread inhertance then invoking.:
I dont want async i want sync becuase my client is sync and i would like to be able to just copy code.
Sorry but this don't make sense to me.
TCP is a stream connection, so you don't known when all data are received, you are always inform about new data received.
So do it synchronously or asynchronously is just a matter of "feeling".And using synchronous TCP transfer with Qt is a very bad idea, you are locking a thread/wasting CPU and memory for nothing.
-
@raketmus said in QThread inhertance then invoking.:
Becuase when sending and reciveing binary you have to send how long the data is gonna be
And what is the problem? You need a some kind of protokol, like: send the length and then actual data. Then you receive the data asynchronously you accumulate the data in a buffer until you got the whole data (#bytes=length). This is how it works...