how move to thread works
-
Here is my program of server,in which i have used movetothread concept.i am confused about when moveto thread call everytime new client connect. Is it generate new thread every time?
myserver.cpp
void MyServer::incomingConnection(qintptr s){
qDebug()<<"Map SIze";//<<cMap.size(); qDebug()<<"Inside Incoming"; QThread *mythread=new QThread(); WorkerS *worker=new WorkerS(s); qDebug()<<"thread of Incommingconection : "<<QThread::currentThread(); worker->moveToThread(mythread); // qDebug()<<"thread of Incommingconection after moveto thread : "<<QThread::currentThread();
// connect(this,SIGNAL(connectclient()),worker,SLOT(connectionDone()),Qt::DirectConnection);
connect(worker,SIGNAL(pushclient(QTcpSocket *,qintptr)),this,SLOT(clientList(QTcpSocket *,qintptr)),Qt::UniqueConnection);
connect(worker,SIGNAL(aboutToWrite(QString, QTcpSocket *)),this,SLOT(messageFromclient(QString, QTcpSocket *)));
connect(worker,SIGNAL(clientleft(QTcpSocket *)),this,SLOT(RemainingClients(QTcpSocket *)));
connect(mythread,SIGNAL(finished()),mythread,SLOT(deleteLater()));mythread->start();
worker->connectionDone();
ClientDescArray.push_back(s);
for(int i=0;i<ClientDescArray.size();i++){
}
qDebug()<<"Thread finder "<<QThread::currentThread();qDebug()<<"Signal Emmited";
}
void MyServer::clientList(QTcpSocket *g, qintptr sockD){qDebug()<<"thread of clientlist slot : "<<QThread::currentThread(); clients.push_back(qMakePair(g,QString::number(sockD))); qDebug()<<"SOcket in list"<<g <<" "<<clients; qDebug()<<"Client Vec Size"<<clients.size();
for(int i=0;i<clients.size();i++){
qDebug()<<i<<" Client list"<<clients[i];
qDebug()<<i<<" Client list"<<clients[i].first->socketDescriptor();
}
for(int i=0;i<clients.size();i++){
for(int j=0;j<clients.size();j++){
if(i!=j){
clients[i].first->write(clients[j].second.toStdString().c_str());
qDebug()<<i<<" Client "<<clients[i].first<<clients[j].second;
}}
}
qDebug()<<"Thread finder clientlist "<<QThread::currentThread();
}
void MyServer::messageFromclient(QString B, QTcpSocket *t){
QString sender_name;qDebug()<<"SOcket in msgfromclient slot: "<<t<<QThread::currentThread();
qDebug()<<"SOCK D"<<t->socketDescriptor();
for (int i = 0; i < clients.size(); i++) {
if (clients[i].first == t) {
sender_name = clients[i].second;
}
}
if(B.contains(":")){
QStringList ls= B.split(':');
qDebug()<<ls.first()<<ls.last();
QString msg=ls.last();
msg=sender_name+": "+msg ;
for(int i=0;i<clients.size();i++){
if(ls.first()==clients[i].second){
clients[i].first->write(msg.toStdString().c_str());
}
}} else{ for(int i=0;i<clients.size();i++){ clients[i].first->write(B.toStdString().c_str()); qDebug()<<clients[i]<<" "<<B;
}
}}
void MyServer::RemainingClients(QTcpSocket *g){
qDebug()<<"Clients remaining "<<QThread::currentThread();qDebug()<<"Clients remaining "<<QThread::currentThread(); for(int i=0;i<clients.size();i++){ if(clients[i].first==g){ clients.erase(clients.begin()+i); } } qDebug()<<"Clients still connected"; for(int i=0;i<clients.size();i++){ qDebug()<<clients[i].first->socketDescriptor(); }
}
myworker.cpp
#include "workers.h"
#include"myserver.h"
#include<QThread>QTextStream cin(stdin);
QVector<QTcpSocket*>worClients;
WorkerS::WorkerS(qintptr sd, QObject *parent) : QObject(parent)
{
qDebug()<<"thread of Worker constructor : "<<QThread::currentThread();sockD=sd;
}
void WorkerS::connectionDone(){QTcpSocket *m_socket=new QTcpSocket(); connect(m_socket,SIGNAL(readyRead()),this,SLOT(readData())); connect(m_socket,SIGNAL(disconnected()),this,SLOT(RemoveClient())); qDebug()<<"SOcket worker "<<m_socket; qDebug()<<"Connection Worker"; qDebug()<<"thread of Worker connectionDone : "<<QThread::currentThread(); qDebug()<<"SOckDEsc Before "<<sockD; if(!m_socket->setSocketDescriptor(sockD)){ qDebug()<<"Error Descriptor"; } else{ worClients.push_back(m_socket); m_socket->write("welcome to the jungle...haha!!!"); qDebug()<<"clients in worker"<<worClients.size(); qDebug()<<"SOckDEsc "<<m_socket->socketDescriptor(); qDebug()<<"thread of Worker connectionDone after setting socketdescriptor : "<<QThread::currentThread(); emit pushclient(m_socket,sockD); } qDebug()<<"SOcket"<<m_socket; qDebug()<<"Connected...";
}
void WorkerS::readData(){
QTcpSocket socket=(QTcpSocket)sender();// struct sockaddr_in ;
qDebug()<<"Reading...";
qDebug()<<"SOcket"<<socket;
qDebug()<<"thread of Worker readdata slot : "<<QThread::currentThread();QByteArray B=socket->readAll(); qDebug()<<sockD<<B; QString data_string(B); qDebug()<<data_string; data_string.split(" ");
// QString::indexOf(" ");
qDebug()<<"writting...";
qDebug()<<"Clients WRITTIng remaining "<<QThread::currentThread();
emit aboutToWrite(data_string,socket);}
void WorkerS::RemoveClient(){for(int i=0;i<worClients.size();i++){ if(worClients[i]->state()!=QAbstractSocket::ConnectedState){ qDebug()<<"Hope it works"; emit clientleft(worClients[i]); worClients.erase(worClients.begin()+i); } } for(int i=0;i<worClients.size();i++){ qDebug()<<"sock Remianing"<<worClients[i]; //worClients[i]->write("client left gracefully"); } //emit clientleft(sockD); qDebug()<<"emitted deleted client "<<QThread::currentThread(); qDebug()<<"New Size"<<worClients.size();
}
/*void WorkerS::disconnected(){qDebug()<<sockD<<": Disconnected"; m_socket->deleteLater(); exit(0);
}
void WorkerS::readSlot(){
// emit aboutToread();
}
void WorkerS::writeSlot(){}
*/
output :
Here you can see that every time new client connected and it call readdata() function,new thread is created for each client. so my question is new thread is called every time for each client or instance of the thread is created"
-
Hi,
No,
moveToThread
doesn't create a new thread. You have to create it yourself, otherwise how you could pass said thread as parameter to the function.You are creating a new thread every time
incomingConnection
is called. -
A bit off topic, but just some performance advice.. In a client/server architecture I would use a thread pool rather than creating a thread per connection. This way you can a few threads handle all the socket IO. I would make the thread pool configurable in order to scale your server with load though.
If you create a thread per connection and you get a couple hundred connections, you will kill your machine's performance. All that thread switching the cpu would have to handle for such simple acts in each thread would bring it to it's knees. Assuming you even have a system capable of allocation that many threads/has available handles.
-
Hi,
No,
moveToThread
doesn't create a new thread. You have to create it yourself, otherwise how you could pass said thread as parameter to the function.You are creating a new thread every time
incomingConnection
is called. -
Hi,
No,
moveToThread
doesn't create a new thread. You have to create it yourself, otherwise how you could pass said thread as parameter to the function.You are creating a new thread every time
incomingConnection
is called.@SGaist As you have suggested .i made changes in my code and my problem is solved.i have moved QThread *mythread=new QThread() in to headerfile of myserver.cpp(in private ) instead of from incommingconnection().it create only one thread and readding of all clients is executing in that one thread.
am i doing right? -
If the goal was to move all clients in the same thread, then yes.