PDA

View Full Version : QThread count in Qt applications.



hashimov
21st October 2010, 18:57
Hi. For testing i create 1000 threads in my application with QThread class, and all this threads are running. But i get QThread::start: Failed to create thread (The access code is invalid.) this message. What is problem?

my class is.


#include <QtCore/QCoreApplication>
#include "mythread.h"

......int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

QCoreApplication * app = qApp;

for (int i=0; i < 1000; i++)
{
MyThread * thread = new MyThread(i, app);
MyThread::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
MyThread::connect(thread, SIGNAL(terminated()), thread, SLOT(deleteLater()));
thread->start();
}

return a.exec();
}

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QtCore/QThread>
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(int number, QObject *parent = 0);
void run();
private:
int number;
signals:
public slots:
};
#endif // MYTHREAD_H
#include "mythread.h"
#include <stdio.h>

MyThread::MyThread(int number, QObject *parent) :
QThread(parent), number(number)
{
}

void MyThread::run()
{
while (true)
{
//printf("Running thread number: %d\n", number);
QThread::msleep(10000);
}
}

SixDegrees
21st October 2010, 20:02
Every thread consumes resources. Just as one example, each thread has a stack associated with it. A typical stack size might be a megabyte, although this varies considerably from machine to machine. A thousand threads, then, would consume a gigabyte of memory in stack space alone, along with whatever other memory is required by stack overhead.

Everything on a computer has limits. If any were infinite, they would have trouble fitting it all in that little box.

hashimov
21st October 2010, 20:22
Thank you, for your answer. Can you help me how solve this problem, if it resolvable?

wysota
21st October 2010, 20:29
Do you really need 1000 threads? Do you have 1000 cores in your computer?

SixDegrees
21st October 2010, 20:30
On some systems (Linux) you can adjust the per-thread stack size. I don't know if this is possible on Windows; probably.

The real question is: what do you need 1000 threads for? Unless you have 1000 processors, it's unlikely there's any good reason to spawn so many. You're probably better off using a thread pool that reuses a fixed (small) number of threads; Qt provides a QThreadPool class for this purpose, although I've never used it.

hashimov
21st October 2010, 20:43
Actually i need this count of threads for listening QTcpSocket. My program listens some devices which sends some tcp packeges to my server, and my server creates threads for every device, such as Fortune Server Example in qt examles. and count of this devices may by 10000 and more.

wysota
21st October 2010, 20:44
In that case don't create one thread per device, there is no need to do that, you can handle all clients in one thread.

hashimov
21st October 2010, 20:44
My program works fine for probabalu 700 threads. But when count increases program gets QThread::start: Failed to create thread (The access code is invalid.) message.

hashimov
21st October 2010, 20:46
No. in case of one thread there may be some waitings, an other way every my thread also commonicates with QTcpSocket individually. I need per thread for per device.

wysota
21st October 2010, 20:49
No, you don't need one thread per device. If you have 1000 threads and one CPU then you will wait much much much much much longer than when handling all connections in one thread. This is a common legend that you need one thread per connection to be able to handle multiple clients and here we fight very hard to counter this riddiculous belief.

hashimov
21st October 2010, 21:02
Ok, assume that all connections are one threads. Then in this case 999 QTcpSocket-s must wait in some loop while one QTcpSocket is reading data from socket? Take into consideration that every device send the packages every 1 second or 0.1 second. Would be there pending packeges for reading?

wysota
21st October 2010, 21:09
Ok, assume that all connections are one threads. Then in this case 999 QTcpSocket-s must wait in some loop while one QTcpSocket is reading data from socket?
No loop. If you have 1000 threads and one CPU then 999 sockets are waiting anyway. And the CPU has to waste its cycles to context switch between those 1000 threads.


Take into consideration that every device send the packages every 1 second or 0.1 second.
A lot can happen within 0.1 seconds. Especially that not all devices send data at the same time. This would result in network conflicts anyway.


Would be there pending packeges for reading?
I don't know how large each block of your data is but assuming it is somewhere between 100 bytes and 1 kilobyte per 0.1 second then one thread will easily handle many such connections. If it can handle 1000 - I don't know, probably yes but if you have two CPUs and possibly more than one network card then it might be wise to distribute the traffic across two network cards and two threads. With 1000 threads you're just wasting resources.

hashimov
21st October 2010, 21:14
Ok, i will change my code for one thread and will test how behaves in this case my program, after testing i will write my results here:))

What is benefit of Threaded Fortune Server Example as mentioned in Qt Examples and demos???

SixDegrees
21st October 2010, 21:28
What is benefit of Threaded Fortune Server Example as mentioned in Qt Examples and demos???

It's meant as an example. Not a particularly good one when it comes to real-world implementation.

The traditional way of handling socket connections uses a single process that listens on the socket and forks() itself as needed. Threads can handle this using a lighter weight framework, but they still come at a price of stack space and other overhead.

Use a thread pool that recycles a fixed number of threads. If you think you need more, it's easy to increase the number of threads, but as others have already pointed out you're going to be much more limited by network conflicts and CPU contention anyway; "waiting" for a thread to become available is simply a reflection of other hardware realities that can't be overcome. Your hardware can't physically handle 1000 simultaneous connections - it can only handle one at a time.

wysota
21st October 2010, 21:29
What is benefit of Threaded Fortune Server Example as mentioned in Qt Examples and demos???
Benefit over what? Over not having it that example at all? Or do you mean something different.

Please don't reply to your own posts, edit your original posts instead.

hashimov
22nd October 2010, 12:45
I change my code for one thread for serving all tcpsocket. And the result was no effective. because when sockets count increases the waiting packages also increases, and the bad think that it concatenates the packages which comes from the same socket, for example the socket every 1 second sends "Socket", in this case in my database inserts "SocketSocket", some times many times "SocketSocket....Socket". And CPU works in 99%. But in multi thread version CPU works 1-2%.

wysota
22nd October 2010, 12:58
I change my code for one thread for serving all tcpsocket. And the result was no effective. because when sockets count increases the waiting packages also increases, and the bad think that it concatenates the packages which comes from the same socket, for example the socket every 1 second sends "Socket", in this case in my database inserts "SocketSocket", some times many times "SocketSocket....Socket". And CPU works in 99%. But in multi thread version CPU works 1-2%.

My assumption is that you simply didn't do it correctly.

hashimov
22nd October 2010, 13:10
// #include "gpstcpserver.h"

#ifndef GPSTCPSERVER_H
#define GPSTCPSERVER_H

#include <QtCore/QObject>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
#include "gpstcpsocket.h"

class GpsTcpServer : public QTcpServer
{
public:
explicit GpsTcpServer(QObject * parent = 0);

virtual void incomingConnection ( int socketDescriptor );

int _count;
};

#endif


// gpstcpserver.cpp

#include "gpstcpserver.h"

GpsTcpServer::GpsTcpServer(QObject *parent)
: QTcpServer(parent), _count(0)
{
}

void GpsTcpServer::incomingConnection(int socketDescriptor)
{
GpsTcpSocket * socket = new GpsTcpSocket(++_count, this);

if (!socket->setSocketDescriptor(socketDescriptor)){
delete socket;
}
}


// gpstcpsocket.h

#ifndef GPSTCPSOCKET_H
#define GPSTCPSOCKET_H

#include <QtCore/QObject>
#include <QtNetwork/QAbstractSocket>
#include <QtNetwork/QTcpSocket>

class GpsTcpSocket : public QTcpSocket
{
Q_OBJECT
public:
GpsTcpSocket(long id, QObject *parent = 0);

private:
long _id;

signals:

public slots:
void gpsReadReady();
void gpsConnected();
void gpsDisconnected();
void gpsError( QAbstractSocket::SocketError socketError );

};

#endif // GPSTCPSOCKET_H


// gpstcpsocket.cpp

#include "gpstcpsocket.h"

#include <QtCore/QFile>

GpsTcpSocket::GpsTcpSocket(long id, QObject *parent) :
QTcpSocket(parent), _id(id)
{
connect(this, SIGNAL(readyRead()), this, SLOT(gpsReadReady()));
connect(this, SIGNAL(connected()), this, SLOT(gpsConnected()));
connect(this, SIGNAL(disconnected()), this, SLOT(gpsDisconnected()));
connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(gpsError(QAbstractSocket::SocketError)));
}

void GpsTcpSocket::gpsReadReady()
{
int availableBytes = bytesAvailable();

char * data = new char[availableBytes];
read(data, availableBytes);

/*QFile file("c:/data.txt");
file.open(QFile::Append);
file.write(data, availableBytes);
file.close();*/

delete [] data;
}

void GpsTcpSocket::gpsConnected()
{
}

void GpsTcpSocket::gpsDisconnected()
{
}

void GpsTcpSocket::gpsError(QAbstractSocket::SocketErro r socketError)
{
Q_UNUSED(socketError);
}


// main.cpp

#include <QtCore/QCoreApplication>
#include <QtNetwork/QHostAddress>
#include "gpstcpserver.h"

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

GpsTcpServer server;
server.listen(QHostAddress::Any, 1000);

return a.exec();
}

wysota
22nd October 2010, 13:15
Please do not inline large amount of code in your posts or at least use proper bbcode tags.

By the way, is this code supposed to prove anything?

hashimov
22nd October 2010, 13:18
wysota, i posted my code, what is incorrect?

wysota
22nd October 2010, 13:25
It's correct but it doesn't do anything. The only thing I see incorrect (but only because of knowing what "issues" you experience) is that you read all the data each and every time and that's why you get "SocketSocket" instead of two "Socket" reads. It's because you probably don't understand (or just forgot about it) that TCP is a stream of bytes and is not record-based. The fact that on the sending side you write two "Socket" words separately won't cause the receiving end to read two datagrams containing one "Socket" entry each. And you get 99% of the CPU usage probably because you are dumping the contents of the sockets to the console which is terribly time consuming.

tbscope
22nd October 2010, 13:41
Some inspiration:
http://www.qtcentre.org/wiki/index.php?title=Multi_client_server_without_thread ing