Connect multiple clients using single thread with synchronous or asynchronous?
-
a few months ago,i had asked some relative questions about qt tcp network programming for my project. And finally the software came out. But after learned more detail about qt
event mechans
andsignals -slots
realization. I have some worry about my program performance and stability.The key problem is that server using a single thread for handle multiple tcpsockets. the brief introduction code for realization:
incomingConnection
function is writen as following: twoQSignalMapper
are used for map each socketSlotReadyRead
andSlotDisconnected
void ServerModule::incomingConnection(qintptr socketDescriptor) { m_tcpSocket = new QTcpSocket(this); if (!m_tcpSocket->setSocketDescriptor(socketDescriptor)) { return; } connect(m_tcpSocket, SIGNAL(readyRead()), m_readyReadSignalMapper, SLOT(map())); m_readyReadSignalMapper->setMapping(m_tcpSocket, m_tcpSocket); connect(m_tcpSocket, SIGNAL(disconnected()), m_disconnectedSignalMapper, SLOT(map())); m_disconnectedSignalMapper->setMapping(m_tcpSocket, m_tcpSocket); }
- the sever construct function:
ServerModule::ServerModule(QObject * parent) : QTcpServer(parent),m_readyReadSignalMapper(new QSignalMapper(this)),m_disconnectedSignalMapper(new QSignalMapper(this)) { connect(m_readyReadSignalMapper, SIGNAL(mapped(QObject *)), this, SLOT(SlotReadyRead(QObject *))); connect(m_disconnectedSignalMapper, SIGNAL(mapped(QObject *)), this, SLOT(SlotDisconnected(QObject*))); ......other code }
SlotReadyRead
andSlotDisconnected
functions are every normal,it convertsQObject* socketObject
toQTcpSocket *socket
and then do some work.
So i have learned that if write like aboving
connect
function with specificconnect mode
Qt::DirectConnection
Qt::QueuedConnection
Qt::BlockingQueuedConnection
Qt::BlockingQueuedConnectionif using single thread,only first mode and second mode can be used . And use first mode, it's synchronous ,if second, it's asynchronous. My program default using first mode, so the
signals -slots
are connected synchronous.So here is my worry:
- How about the single thread performance for handling multiple sockets?can it reach 500 connection /per second concurrency?what's the max connected can be handled?
- if at the same time,multiple sockets are ready to read then called qt core to send
readyRead
signals, theQSignalMapper
can handle it properly? - should I connect
socket
andQSignalMapper
using QueuedConnection mode, because this connecting is not connected immediately, it's usingevent queue
andpostEvent
to connect. so its asynchronous. Is in this situation,the concurrency request can be handled?
-
a few months ago,i had asked some relative questions about qt tcp network programming for my project. And finally the software came out. But after learned more detail about qt
event mechans
andsignals -slots
realization. I have some worry about my program performance and stability.The key problem is that server using a single thread for handle multiple tcpsockets. the brief introduction code for realization:
incomingConnection
function is writen as following: twoQSignalMapper
are used for map each socketSlotReadyRead
andSlotDisconnected
void ServerModule::incomingConnection(qintptr socketDescriptor) { m_tcpSocket = new QTcpSocket(this); if (!m_tcpSocket->setSocketDescriptor(socketDescriptor)) { return; } connect(m_tcpSocket, SIGNAL(readyRead()), m_readyReadSignalMapper, SLOT(map())); m_readyReadSignalMapper->setMapping(m_tcpSocket, m_tcpSocket); connect(m_tcpSocket, SIGNAL(disconnected()), m_disconnectedSignalMapper, SLOT(map())); m_disconnectedSignalMapper->setMapping(m_tcpSocket, m_tcpSocket); }
- the sever construct function:
ServerModule::ServerModule(QObject * parent) : QTcpServer(parent),m_readyReadSignalMapper(new QSignalMapper(this)),m_disconnectedSignalMapper(new QSignalMapper(this)) { connect(m_readyReadSignalMapper, SIGNAL(mapped(QObject *)), this, SLOT(SlotReadyRead(QObject *))); connect(m_disconnectedSignalMapper, SIGNAL(mapped(QObject *)), this, SLOT(SlotDisconnected(QObject*))); ......other code }
SlotReadyRead
andSlotDisconnected
functions are every normal,it convertsQObject* socketObject
toQTcpSocket *socket
and then do some work.
So i have learned that if write like aboving
connect
function with specificconnect mode
Qt::DirectConnection
Qt::QueuedConnection
Qt::BlockingQueuedConnection
Qt::BlockingQueuedConnectionif using single thread,only first mode and second mode can be used . And use first mode, it's synchronous ,if second, it's asynchronous. My program default using first mode, so the
signals -slots
are connected synchronous.So here is my worry:
- How about the single thread performance for handling multiple sockets?can it reach 500 connection /per second concurrency?what's the max connected can be handled?
- if at the same time,multiple sockets are ready to read then called qt core to send
readyRead
signals, theQSignalMapper
can handle it properly? - should I connect
socket
andQSignalMapper
using QueuedConnection mode, because this connecting is not connected immediately, it's usingevent queue
andpostEvent
to connect. so its asynchronous. Is in this situation,the concurrency request can be handled?
@SpartaWHY117 said in Connect multiple clients using single thread with synchronous or asynchronous?:
And use first mode, it's synchronous ,if second, it's asynchronous
No, your code is asynchronous, the synchronous way is to use
waitForReadyRead()
and methods like those that are a bad idea in 90% of the cases.How about the single thread performance for handling multiple sockets?can it reach 500 connection /per second concurrency?what's the max connected can be handled?
It can, performance depends on how much data is steraming every time. if 500 clients are streaming live video constantly it will basically halt your server, if each client sends a short string of text every minute you won't notice the performance decrease at all.
at the same time,multiple sockets are ready to read then called qt core to send readyRead signals, the QSignalMapper can handle it properly?
Yes, don't worry
should I connect socket and QSignalMapper using QueuedConnection mode, because this connecting is not connected immediately, it's using event queue and postEvent to connect. so its asynchronous. Is in this situation,the concurrency request can be handled?
No real point.
What I usually do is have a
QList<QThread*> m_threadPool
and aint m_threadIndex = -1;
as members then in incoming connection:if(m_threadPool.size()<qMax(1,QThread::idealTheradCount())){ QThread* tempThread=new QThread; m_threadPool.append(tempThread); connect(tempThread,SIGNAL(finished()),tempThread,SLOT(deleteLater())); } if(++m_threadIndex>=m_threadPool.size()) m_threadIndex=0; QThread* currentThread = m_threadPool.at(m_threadIndex); tcpSocket->movetoThread(currentThread);
then in
~ServerModule()
callforeach(QThread* tempThread ,m_threadPool) tempThread.stop();
P.S.
m_tcpSocket
should be a local variable, not a member, there is no point storing the last added socket -
I forgot the most important part: the slot connected to readyRead and all socket writing operations should be done in the thread. Subclass QTcpSocket and do the work there
@VRonin thanks for your answer. I remembered i haved asked should use multiple threads for server? a few months ago ,in that answer you said using multiple threads may be better.
but if changed it into multiple thread program, have you test the max connection can be handled?after all the context switch between threads also need overhead.
And what's usual method to control synchronization value?for example, i need to maintain the connection sockets in a list, but when one connection or disconnect, in it's running thread slot function , how to notify the the main thread that socket list it's size has changed? use
signals -slots
is enough?or should build a thread-safe list? -
@VRonin thanks for your answer. I remembered i haved asked should use multiple threads for server? a few months ago ,in that answer you said using multiple threads may be better.
but if changed it into multiple thread program, have you test the max connection can be handled?after all the context switch between threads also need overhead.
And what's usual method to control synchronization value?for example, i need to maintain the connection sockets in a list, but when one connection or disconnect, in it's running thread slot function , how to notify the the main thread that socket list it's size has changed? use
signals -slots
is enough?or should build a thread-safe list?@SpartaWHY117 said in Connect multiple clients using single thread with synchronous or asynchronous?:
I remembered i haved asked should use multiple threads for server? a few months ago ,in that answer you said using multiple threads may be better.
As mentioned in general it is but if your system is not under massive load it's ok to leave it single threaded
but if changed it into multiple thread program, have you test the max connection can be handled?
No, that's an OS specific limitation but usually is not really restrictive and you don't need to write any code to manage it anyway
after all the context switch between threads also need overhead.
Normally all the overhead is managed by Qt itself
And what's usual method to control synchronization value?for example, i need to maintain the connection sockets in a list, but when one connection or disconnect, in it's running thread slot function , how to notify the the main thread that socket list it's size has changed? use
signals -slots
is enough?or should build a thread-safe list?Unless you have special needs make your classes reentrant use signal and slots and you can (almost) forget you have multiple threads
-
@SpartaWHY117 said in Connect multiple clients using single thread with synchronous or asynchronous?:
I remembered i haved asked should use multiple threads for server? a few months ago ,in that answer you said using multiple threads may be better.
As mentioned in general it is but if your system is not under massive load it's ok to leave it single threaded
but if changed it into multiple thread program, have you test the max connection can be handled?
No, that's an OS specific limitation but usually is not really restrictive and you don't need to write any code to manage it anyway
after all the context switch between threads also need overhead.
Normally all the overhead is managed by Qt itself
And what's usual method to control synchronization value?for example, i need to maintain the connection sockets in a list, but when one connection or disconnect, in it's running thread slot function , how to notify the the main thread that socket list it's size has changed? use
signals -slots
is enough?or should build a thread-safe list?Unless you have special needs make your classes reentrant use signal and slots and you can (almost) forget you have multiple threads
@VRonin
thanks again