PDA

View Full Version : Network programming and the main thread



invictus
15th March 2007, 18:29
Hi

I see from the trolltech examples that its not unusual to use the signal/slot mechanism for socket IO, and I was wondering if this is really a good idea? Although I am new to QT I have some previous experience with gui and network programming and the problem is always the same; doing network/io stuff and parsing will lead to unresponsive programs if not done in a custom thread.

Let me illustrate with an example from the broadcasting receiver example:

In the contructor the following is run:

udpSocket = new QUdpSocket(this);
udpSocket->bind(45454);

connect(udpSocket, SIGNAL(readyRead()),
this, SLOT(processPendingDatagrams()));


then in the processPendingDatagrams() the following is run:

while (udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(datagram.data(), datagram.size());
statusLabel->setText(tr("Received datagram: \"%1\"")
.arg(datagram.data()));
}


Pretty much straight forward and easy to understand. However as far as I know (which may not count for much when it comes to QT) these signals/slots are run on the main-thread that is executed as app.exec() during the main procedure.

Now, I would imagine that if this application did receive alot of messages it would become slow and unresponsive. Why? Well first of all the slot would be called all the time, wich obviously would take some cpu-time. Furthermore the code within the slot would also be run very often which also would demand its share of the cpu. So wouldnt this lead to unresponsive UI _if_ I had buttons and such that normally would be clicked by the user? The usual method for fixing this in other languages/frameworks would be to create another thread with blocking socket code. I am not sure if this is needed in QT and therefore I ask you guys. What do you think about this issue?

jacek
15th March 2007, 19:12
You can create that socket in a non-GUI thread and still use signals & slots mechanism. The only requirement is that you must start the event loop in that new thread.

invictus
15th March 2007, 20:06
You can create that socket in a non-GUI thread and still use signals & slots mechanism. The only requirement is that you must start the event loop in that new thread.

The app.exec() or another event-loop?


So basicly the problem I described is also valid for QT4 ?

jacek
15th March 2007, 20:28
The app.exec() or another event-loop?
That thread's event loop (QThread::exec()).


So basicly the problem I described is also valid for QT4 ?
On the contrary, there is no problem in Qt4 (at least when it comes to networking and threads). If you flood your application with thousands of UDP messages it will become unresponsive, just as any other program.

invictus
15th March 2007, 22:12
That thread's event loop (QThread::exec()).

Ok I get it. Smart way of doing things really. So lets say I create a thread with a event-loop to take care of these signals. After parsing the data and doing all the heavy IO operations I want to pass the data to the UI. With for instance Java/Swing you have the invokeLater method to push some code onto the UI-thread event queue for later execution. Is there anything similar for QT4? I heard somewhere that with signals and slots I didnt have to care about these things as they were thread-safe, but I would rather get this confirmed than to discover it after thousands of lines of code.

jacek
16th March 2007, 00:25
Ok I get it. Smart way of doing things really. So lets say I create a thread with a event-loop to take care of these signals.
That event loop is also necessary to handle the socket.


Is there anything similar for QT4? I heard somewhere that with signals and slots I didnt have to care about these things as they were thread-safe, but I would rather get this confirmed than to discover it after thousands of lines of code.
You can use queued signal-slot connections safely. They were especially designed to handle the communication between threads (in fact they're just a more pleasant version of events).

Just watch out for automatic connections when dealing with threads.