PDA

View Full Version : QThread for Multithreading



strateng
8th June 2010, 02:45
Hey,

I was wondering if someone could show some example coding for using QThread within a class of another. I currently have written has the following functions:

Server(void);
lookforconnection();
read();
disconnect();

I am having problems with when I click on a button which loops on lookforconnection() as it completely freezes the form but is running in the background. I would like to thread that function so that it just loops in the background and looks for connections.

Thanks,
Strateng

Coises
8th June 2010, 03:41
I am having problems with when I click on a button which loops on lookforconnection() as it completely freezes the form but is running in the background. I would like to thread that function so that it just loops in the background and looks for connections.

Probably you are not going about this in the right way.

Consider starting a QTimer in your lookforconnection() function that you have connected to a “check for connection” slot. Each time the slot is triggered it checks for an available connection. If it finds one, it cancels the timer and does whatever you do when you find a connection; otherwise, it returns, leaving the timer to trigger the slot again at the defined interval.

If you just loop in another thread, it will still consume CPU (degrading performance of the GUI thread and other applications running at the same time), even though it won’t block the GUI thread entirely. That’s reasonable if you are doing actual computational work in the thread, but if you’re just polling for a desired condition, I suggest using a QTimer as described above instead. The extra thread won’t gain you anything but complexity.

strateng
8th June 2010, 04:25
Hey,

Thanks for the reply. Oh the suggestion you gave me, I have already done coding for that. I was just looking for example on how to implement a QThread (which does a function which I create) inside a class?

Thanks,
Strateng


Probably you are not going about this in the right way.

Consider starting a QTimer in your lookforconnection() function that you have connected to a “check for connection” slot. Each time the slot is triggered it checks for an available connection. If it finds one, it cancels the timer and does whatever you do when you find a connection; otherwise, it returns, leaving the timer to trigger the slot again at the defined interval.

If you just loop in another thread, it will still consume CPU (degrading performance of the GUI thread and other applications running at the same time), even though it won’t block the GUI thread entirely. That’s reasonable if you are doing actual computational work in the thread, but if you’re just polling for a desired condition, I suggest using a QTimer as described above instead. The extra thread won’t gain you anything but complexity.

tbscope
8th June 2010, 04:39
Why don't you use the newConnection signal? Then you don't need threads.

strateng
8th June 2010, 04:45
Hey,

Thanks for the reply. Does newConnection signal work with just C++ Programming not QT cause I am currently writing the TCP connection in C++? Also with my question about QThread is that I want the program multithreading as I intend to use a QGraphicsView loading up pictures after data has been received through the TCP Connection and I want the program to be able to listen to several connections at once?

Thanks,
Strateng


Why don't you use the newConnection signal? Then you don't need threads.

tbscope
8th June 2010, 04:50
Why won't you use QTcpSocket?

A server can listen to multiple connections at once without using threads. I don't know why people tend to think they need threads. It's only when you want to do complex mathematical calculations for the items on your graphics view that it becomes interesting to put those calculations in a separate thread.

strateng
8th June 2010, 04:53
Hey,

I'm connecting to a program written outside of QT so I don't think I can use QTcpSocket can I?

I was recommended to use threads (QThread) as my program has a lot of different functions which some may require to be ran at the same time?

Thanks,
Strateng


Why won't you use QTcpSocket?

A server can listen to multiple connections at once without using threads. I don't know why people tend to think they need threads. It's only when you want to do complex mathematical calculations for the items on your graphics view that it becomes interesting to put those calculations in a separate thread.

Coises
8th June 2010, 04:55
I was just looking for example on how to implement a QThread (which does a function which I create) inside a class?

To use QThread you must derive a class from it in which you re-implement the virtual member function QThread::run() to do what you want, and/or you define slots to which signals from other threads can connect. Then you construct an object of your class and call or signal QThread::start() to begin execution. Read the articles listed at Thread Support in Qt (http://doc.trolltech.com/latest/threads.html) for details and examples.

I’m not quite sure what you mean by “inside a class.” If you mean that you want the class derived from QThread to be a nested class, that can be awkward, because the Meta-Object Compiler does not support the Q_OBJECT macro in nested classes, so you would be unable to define any signals or slots. However, since nested classes in C++ accomplish nothing more than name-scoping, it shouldn’t matter much if you need to make it a separate class.

If you’re thinking that you can somehow use QThread as something you “call” without deriving a class from it to define the behavior you want... that is not possible.

strateng
8th June 2010, 05:03
Hey,

Thanks for the help I'll try going through that and see what I can get from it. Its just currently within my coding I only have one class so I was wondering if I would be able to multithread within it so that I am able to run more than one function at a time?

Thanks,
Strateng


To use QThread you must derive a class from it in which you re-implement the virtual member function QThread::run() to do what you want, and/or you define slots to which signals from other threads can connect. Then you construct an object of your class and call or signal QThread::start() to begin execution. Read the articles listed at Thread Support in Qt (http://doc.trolltech.com/latest/threads.html) for details and examples.

I’m not quite sure what you mean by “inside a class.” If you mean that you want the class derived from QThread to be a nested class, that can be awkward, because the Meta-Object Compiler does not support the Q_OBJECT macro in nested classes, so you would be unable to define any signals or slots. However, since nested classes in C++ accomplish nothing more than name-scoping, it shouldn’t matter much if you need to make it a separate class.

If you’re thinking that you can somehow use QThread as something you “call” without deriving a class from it to define the behavior you want... that is not possible.

tbscope
8th June 2010, 05:37
First let me make clear that you do not have to follow anything I say. I'm just interested in why you want to do some things as I might learn something from it.


I'm connecting to a program written outside of QT so I don't think I can use QTcpSocket can I?
First question, you are using a tcp connection to this other program?
Second question, if so, why can't you use QTcpSocket?


I was recommended to use threads (QThread) as my program has a lot of different functions which some may require to be ran at the same time?
Let me destroy one of your dreams (or ideas) right away: on a normal computer, nothing can run at the same time, even when using threads. Every instruction follows another one.
Threads are a way for the operating system to split the workload of long duration loops into manageable parts so each part can run for a certain amount of time. This may look like the code is run at once, while actually it isn't. Total calculation times usually remain the same.

For simple things, like sending or receiving data in chunks (little parts), you do not nead threads as the operating system finds enough time between sending and receiving the data to schedule other things. In fact, what you do when using asynchronous sockets is do what the operating system would do when threading, but without the difficulties of using threads and mutexes and locks etc...

strateng
8th June 2010, 08:00
Hey,

Actually I never tested it but I just checked and yes you're right there is nothing wrong with using QTcpSocket.

Oh ok. Would you by any chance example coding for QThread being implemented?

Thanks,
Strateng


First let me make clear that you do not have to follow anything I say. I'm just interested in why you want to do some things as I might learn something from it.


First question, you are using a tcp connection to this other program?
Second question, if so, why can't you use QTcpSocket?


Let me destroy one of your dreams (or ideas) right away: on a normal computer, nothing can run at the same time, even when using threads. Every instruction follows another one.
Threads are a way for the operating system to split the workload of long duration loops into manageable parts so each part can run for a certain amount of time. This may look like the code is run at once, while actually it isn't. Total calculation times usually remain the same.

For simple things, like sending or receiving data in chunks (little parts), you do not nead threads as the operating system finds enough time between sending and receiving the data to schedule other things. In fact, what you do when using asynchronous sockets is do what the operating system would do when threading, but without the difficulties of using threads and mutexes and locks etc...

squidge
8th June 2010, 08:15
There are example of QThread come with Qt. By using signals and slots you can minimize usage of threads. One class can handle all the connections, and pass along any long functions to other threads.

Coises
8th June 2010, 13:32
I only have one class so I was wondering if I would be able to multithread within it so that I am able to run more than one function at a time?

Short answer: no, you can’t do that.

The long answer — why you can’t, and under what circumstances you might be able to do something that is technically what you said, but almost surely not what you want — you’ll have to understand by reading the Qt documentation. Start at Thread Support in Qt (http://doc.qt.nokia.com/4.6/threads.html).

Following is a partial “example” of using QThread in the situation you described. I haven’t tested it, so it might contain typos, omissions and/or major blunders, but perhaps it will help you:
class connectionInfo {
//...
};

void functionThatGetsAConnection(connectionInfo*);

class getConnection : public QThread {
Q_OBJECT
public:
connectionInfo info;
getConnection() {moveToThread(this);}
protected:
void run() {
functionThatGetsAConnection(&info);
emit gotConnection(this);
}
signals:
void gotConnection(getConnection*);
};

// within your class (which must derive from QObject):

Q_OBJECT
private:
QList<getConnection*> connections;
private slots:
void gotConnection(getConnection*);

// to look for a new connection:

getConnection* con = new getConnection();
connections += con;
connect (con, SIGNAL(gotConnection(getConnection*)), SLOT(gotConnection(getConnection*)), Qt::QueuedConnection);
con->start();

// in gotConnection(getConnection* con):

// ... code that uses con->info ...
connections.removeOne(con);
delete con;
Note particularly that missing from the above is code to clean up getConnections that either never find a connection (time out, or simply fail), or that are still actively looking for a connection when your class is destroyed. Those matters must be addressed, but how to do it is dependent on how functionThatGetsAConnection handles time outs, failures and requests to stop trying.