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 and signals -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:

    1. incomingConnection function is writen as following: two QSignalMapper are used for map each socket SlotReadyRead and SlotDisconnected
    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);
    }
    
    1. 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 
    }
    
    1. SlotReadyRead and SlotDisconnected functions are every normal,it convertsQObject* socketObject to QTcpSocket *socket and then do some work.

    So i have learned that if write like aboving connect function with specific connect mode

    Qt::DirectConnection
    Qt::QueuedConnection
    Qt::BlockingQueuedConnection
    Qt::BlockingQueuedConnection

    if 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:

    1. 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?
    2. if at the same time,multiple sockets are ready to read then called qt core to send readyRead signals, the QSignalMapper can handle it properly?
    3. 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?


  • @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 a int 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() call foreach(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?



  • @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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.