Re: Socket + thread problem
Step 1: do not use threading for socket communication unless you absolutely need to use blocking functions.
Why do you think you need threads?
Ok, now what is wrong with your code. At first sight nothing, but in the background there's a huge problem.
Let's break up your code:
Code:
class MessageThread
: public QThread{
...
};
Your MessageThread class is a subclass of QThread.
A QThread subclass is NOT a new thread. Any MessageThread object lives in the main GUI thread. Keep that in mind for the next lines of code.
Code:
public slots:
void newMessConnection();
signals:
These signals and slots, which you define in your QThread subclass are emitted and called inside the main GUI thread since the QThread object lives in the main gui thread. Try to understand this when we look at the next few lines of code.
Code:
void MessageThread::run()
{
messageSrv = messageServer;
connect(messageServer, SIGNAL(newConnection()), this, SLOT(newMessConnection()));
}
The code in the run() function is being run in a separate thread. So far that's a good idea. You define a new QTcpServer object inside this new thread. So far that's also good. You might want to write messageSrv = new QTcpServer directly though. The problems begin with the connection of the signal and the slot.
The signal newConnection() is being emitted in another thread than the slot newMessConnection(). The slot newMessConnection lives in the main gui thread. Ok, so far that's not a big problem as you want to have some feedback to your main thread.
However, let's look what happens in the slot itself:
Code:
void MessageThread::newMessConnection()
{
QTcpSocket* connection
= messageSrv
->nextPendingConnection
();
}
The connection object is a huge problem. Remember, as I already mentioned several times, the newMessConnection lives in the main gui thread!!!. BUT, messageSrv points to an object in another thread!!!
This is an error!.
This is the exact reason why you get the following error:
Code:
QObject: Cannot create children
for a parent that is in a different thread.
Solution, in pseudo code:
Code:
class MyConnection
: public QObject{
Q_OBJECT
public slots:
void newConnection();
signals:
void error();
};
Then when you use your connection:
MyConnection *connection = new MyConnection;
connect(connection, SIGNAL(error()), this, SLOT(handleError()));
connection->moveToThread(connectionThread);
Edit: Since this question gets asked a lot and since the Qt documentation, at the moment, isn't very clear on this complexity, I'll write a wiki tutorial on threading and sockets this week.
Re: Socket + thread problem
This is my pboject:
suppose that I have some different application A, B, C....
A is the main programm, run and listening in a specific port.
B connect to A. I want than A can be able to communicate with B and receive some information about B. Then I want that I can be able to create another channel of communication (a new socket that work in another port that A tell to B).
But at the same time I want that A can be able to receive other request of connections for example from C o D.
What do you think about this architecture? Is correct use some different thread to the registration step e one different thread to communicate??
Bye, Thanks
Re: Socket + thread problem
Answering for your first question: you can simply do this:
Code:
MessageThread::MessageThread()
{
moveToThread( this );
}
Re: Socket + thread problem
No, DO NOT do what the previous poster said!!!
Re: Socket + thread problem
Quote:
Originally Posted by
borisbn
Answering for your first question: you can simply do this:
Code:
MessageThread::MessageThread()
{
moveToThread( this );
}
Tell me, what will happen with the following code:
Code:
moveToThread(this);
}
protected:
qDebug
() <<
"Custom event" <<
QThread::currentThreadId ();
}
};
//...
Thread thread;
// assuming no thread.start() anywhere here
Will the custom event be delivered or not? And if it will then in context of which thread will it execute?
Re: Socket + thread problem
Easy, easy, tbscope... :)
Why not ? I did moveToThread( this ) and it worked. Please say, what is wrong with that ?
Thanks.
Re: Socket + thread problem
Re: Socket + thread problem
Quote:
Originally Posted by
wysota
// assuming no thread.start() anywhere here
ok, if you will not start the thread, then you will not process events in it. In your example ( but without moveToThread ) events will be processed in main thread, but topic starter ( if I understand correctly ) wanted to process events in separate thread. To do this hi should move objects, that generates events, to that tread. I suggested to move whole object Thread to thread. In this way all it's children will be it thread.
Re: Socket + thread problem
Quote:
Originally Posted by
borisbn
Easy, easy, tbscope... :)
Ohh, sorry, I didn't want to insult you.
Text messages are notoriously difficult to get the emotions from.
It's documented that it is wrong to use moveToThread on the QThread, and if you think about it a little bit you know why it doesn't make sense to do so. See the posts above.
You are correct though that the whole object needs to be moved to another thread. But only the object, not QThread.
Therefor you need to create your own object and then use moveToThread on that object to move it to another thread.
QThread needs to live in the main thread and act as a translator/manager/whatever... between the main thread and the object in the other thread.
Re: Socket + thread problem
Quote:
Originally Posted by
borisbn
ok, if you will not start the thread, then you will not process events in it. In your example ( but without moveToThread ) events will be processed in main thread, but topic starter ( if I understand correctly ) wanted to process events in separate thread. To do this hi should move objects, that generates events, to that tread. I suggested to move whole object Thread to thread. In this way all it's children will be it thread.
There are two things here:
1. Why move the QThread object to another thread instead of creating a separate object and moving THAT to the thread or better yet creating that object in the thread itself?
2. Why move the QThread object to another thread before the thread is actuallys started?
There is also point 3:
- Why use threads here at all?
Re: Socket + thread problem
Ok, I think that I have solve my problem. I have use the first replay of tbscope that is the same that I have read here:
http://labs.trolltech.com/blogs/2010...doing-it-wrong
I think that thread's implementations isn't clear, for example if you read " Threaded Fortune Server Example" you can see that FortuneServer subclass QThread and it can be create confusion.
thanks all fro the replay,
See you, Dax