PDA

View Full Version : How to write on a socket in another thread?



Valheru
10th October 2006, 16:07
Qt doesn't seem to like you trying to write to a socket that is running in another thread :( I have created a thread, which creates a socket, connects it's signals to slots in the parent object, and connects to the server.
However, since the parent object runs in the GUI thread, trying to write to the socket doesn't work. Qt spits out a warning that socket notifiers can't be enabled from another thread. How does one get around this?

jpn
10th October 2006, 16:16
Are you creating the socket in constructor or something? You must create the QTcpSocket object in QThread::run() when the new thread is actually running.



void MyThread::run()
{
QTcpSocket socket;
....
}

Valheru
10th October 2006, 16:37
Yes, I am creating the socket in run()...thats' what's confusing me :( I have connected the readData() signal from the socket to a slot in the class in which the socket is a member of. Using qDebug() I can see that the slot is called, and the it in turn indeed calls the function to actually parse the data. It all goes pearshaped on the line where the function being called tries to write a command to the socket :( Here's the code:

jpn
11th October 2006, 18:33
Like I just mentioned in another thread (http://www.qtcentre.org/forum/f-qt-programming-2/t-problem-closing-a-qmainwindow-in-qt42-3956-post21366.html#post21366):

The destructor of the QThread subclass is executed in the thread where the QThread object lives in (usually same thread where it was created in), not in the thread being executed in QThread::run().

I'm not willing to start examining almost 400 lines of code throughly just for fun, but for what I can see, you are creating the socket in run() and then writing to it in the destructor. These two blocks of code become executed in different threads. I'm also suspecting you having the problem described in this thread (http://www.qtcentre.org/forum/f-qt-programming-2/t-non-gui-thread-blocking-gui-3848.html#14).

Valheru
12th October 2006, 07:54
Thanks, I've just about fixed the problem though, by running a while loop inside run() that checks a command buffer that other threads can write to. This solves the problem, but introduces a new one that when the thread is doing nothing (spinning it's wheels in the while-loop) it uses 100% of the processor :( So now I have to find a way of overcoming that problem.

Valheru
12th October 2006, 10:17
Here is the code if you are interested. It's a bit of a hack, but it works rather well.

vratojr
12th October 2006, 10:36
Hi, consider using a QWaitCondition for doing that thing.
As wysota explained me in the last part of the thread:
http://www.qtcentre.org/forum/f-qt-programming-2/t-thread-problem-with-windows-2623.html
I didn't went through your code, however, for what I have understood you could do something like this:

Create an EventLoop and put the thread(s) inside the event loop.
Let the loop be the interface between your threads by connecting to it the signals
coming from the threads(sockets) you have.

bye.

Valheru
12th October 2006, 11:52
Thanks, but there is really nothing for it to wait for. It just has to wait until a preset amount of time has passed without any activity( ie. user commands or server responses). The so-called "timeout" value. I think that the sleep(0) call that wysota mentioned will work well though.

/edit : hmm, calling sleep(0) at the end of every iteration of my while-loop does nothing for the processor usage :confused: