Threads with QTcpServer
-
I have multiple clients connected to a server . I added each connection to a QList on the server.
So what I notice now , is that when readyRead() ( server side ) is being run by one connection , newConnection() does not start processing until readyRead() is done processing .
What I do in readyRead() is relay the data sent in by one client to all the other clients in the QList .
So what i would like to achieve with multithreading is first of all unblock the newConnection() while readyRead() is running . Secondly I still need to relay the data sent in by one client to all the other clients in the QList ( immediately ) .
I have been looking at the MultiThreaded server examples out there and they don't seem to fit the bill . With each connection running in its own thread , how do I relay data coming from one connection to all other connection threads ? And if I can't do that , then how do I unblock the newConnection() ?
-
Let main thread contain all the QThread objects per connection. Once something of interest happens in any of the threads, relay back to main thread by signal to signal or signal slot connection. Main thread can then call each thread function or again do a signal slot. Signal slot will make sure the functions are called in respective threads and ease serialization headaches.
-
Is it OK to spawn new threads within readyRead() handler and write to sockets within that thread ? What about referencing and running , within the thread , thread parent functions that write to the sockets . Would that cause problems ? Something tells me it would but would like confirmation .
-
[quote author="ChrisW67" date="1376778057"]Don't write long-running or blocking code in the readyRead() handler. The time spent handling data arrival should be measured in milliseconds. What does yours look like?[/quote]
My code is long running so I would like to open some new thread within the readRead() handler and use the thread to send messages back to the clients using the connections in my QList . Is this OK practice ? I am noticing that sometimes data randomly is not sent back to the client ; looks like thread and socket code don't mix well ? What is the proper way to do it , preferably without opening a thread for each connection ?
-
[quote author="pkj__" date="1376731155"]Let main thread contain all the QThread objects per connection. Once something of interest happens in any of the threads, relay back to main thread by signal to signal or signal slot connection. Main thread can then call each thread function or again do a signal slot. Signal slot will make sure the functions are called in respective threads and ease serialization headaches.[/quote]
So i created a new thread within readyRead() and then used signals from this thread to tell the parent thread to do the writing with the sockets . It appears that it works fine now although there are server messages that pop up once in a while :
"QSocketNotifier : socket notifiers cannot be enabled from another thread ."
I am wondering how serious this is or is it just a warning .
But thanks for the suggestion . -
I hope you are doing everything asynchronously.
FYI bug:
https://bugreports.qt-project.org/browse/QTBUG-24451 -
bq. pop up once in a while :
“QSocketNotifier : socket notifiers cannot be enabled from another thread .”
I am wondering how serious this is or is it just a warning .That might happen if you are not using queued connection. Post some code for me to help in a meaningful way.
-
[quote author="pkj__" date="1376982488"]bq. pop up once in a while :
“QSocketNotifier : socket notifiers cannot be enabled from another thread .”
That might happen if you are not using queued connection. Post some code for me to help in a meaningful way.[/quote]I changed the connect statement to use Qt:QueuedConnection . Don't think I am seeing the error message anymore . I think everything is working OK now but I am not sure if I have tested thoroughly enough .
I will see in the next few days .[quote author="pkj__" date="1376982237"]I hope you are doing everything asynchronously.
FYI bug:
https://bugreports.qt-project.org/browse/QTBUG-24451[/quote]Well , I am using waitForBytesWritten() . I think I kind of need it . Hopefully by the time I finish my project , Qt will have fixed the bug :)
-
bq. “QSocketNotifier : socket notifiers cannot be enabled from another thread .”
Once your thread has started make sure that you do not call member functions of objects within that thread. If you do then the code that is run will not be running within the thread, instead it will run locally and any new objects created in that function will infact be created locally and not in the thread!
Generally the way to init a thread is:
Create thread
move required objects into thread (obj.moveToThread(aThread))
Use signal/slot to connect thread.started() signal to your objects "init" function (e.g.
@connect(aThread, SIGNAL(started), anObj, (SLOT(start))@
Start the thread (aThread.start())
After aThread.start() is called do NOT do:
@anObj.start()@
From here on you should only talk to objects within the thread via slot/signalsDoing this wrong can cause hidden issues like the one you had ... learnt from experience : (