PDA

View Full Version : QThread usage and exec()



smahnken
21st August 2008, 16:28
I have some questions regarding the usage of QThread, and I'm hoping someone here can give me a couple pointers. I've read the documentation and the examples on the usage of QThread, but there are some finer points that I must be missing.

First, some background. I'm writing a multi-player puzzle game. The project is being tackled in two pieces: a game server, and a game client. The server will handle all game control and logic, and will have only rudimentary visual display (printf statements to a console... maybe). The client will communicate with the server via TCP/IP and will be responsible for the GUI aspects of the game.

The server class inherits QThread directly. The game flow is such that the server is basically a large state machine, so it doesn't do anything (except track a timer) unless messages come in from the clients. When a message comes in, the server parses it and takes appropriate action. I'd like the server to take as little time as possible so that there's plenty of CPU left for the graphical aspects of the client.

Here's where the questions begin -

1) The documentation states that in order for the thread to handle events, I need to invoke exec(). Do I need to invoke exec() repeatedly (eg in a while( !gameOver ) loop), or just once?

2) Does exec() return immediately when invoked? That is, when does code execution in the thread continue?

3) The documentation mentions that when run() exits the thread stops execution. Am I correct in believing that this would render the thread incapable of handling events? I guess the real question is whether or not I need a captive loop in the run() routine.

Thanks in advance for any help!

jacek
21st August 2008, 16:35
Do I need to invoke exec() repeatedly (eg in a while( !gameOver ) loop), or just once?
Once is enough.


Does exec() return immediately when invoked? That is, when does code execution in the thread continue?
The docs say:
Enters the event loop and waits until exit() is called, returning the value that was passed to exit(). The value returned is 0 if exit() is called via quit().
Which means that it won't return until you invoke QThread::exit().


Am I correct in believing that this would render the thread incapable of handling events?
No, as long the event loop runs, the thread will process events.

smahnken
21st August 2008, 21:01
Thanks for the help!

Another question for the group:

My client acts like it's not getting any time (graphics don't refresh, timed messages never disappear, etc.). Does the event loop yield control when there's no messages, or does it hold onto it? I need it to essentially sleep until messages come in... Is there something else I need to do (set the thread priority lower, perhaps?).

wysota
21st August 2008, 22:35
The event loop runs in a ... loop until the application ends (or actually until exit() is called which most of the times means the same). It doesn't prevent your application from redrawing itself - on the contrary, your widgets couldn't refresh themselves if the loop was not running. The whole point of event driven technologies is that the flow remains with the event loop all the time and that the loop decides what gets executed and when based on events that are generated.

smahnken
21st August 2008, 23:19
Forgive me, but I must be missing something in the way things work here.

My main application is a client (which, of course, has its own event loop). When a game is started, the client launches a separate thread for the server to run in. Said thread executes exec(), giving it an event loop. Do I not now have two event loops running? If so, does the operation of one conflict with the other? That seems to be the way it's behaving, but perhaps I am misinterpreting it.

My intent is to have two separate threads operating independently, one for the server and one for the client. Each needs to handle messages and events without conflicting with each other. Is that possible using the "client launches the server in a separate thread" approach, or do I need to code the two entities as separate apps and execute them independently of each other (like the fortune server/client examples)?

Sorry for the confusion!

wysota
22nd August 2008, 00:13
Do I not now have two event loops running?
Yes, that's correct.


If so, does the operation of one conflict with the other?
No, they do not interfere each other. Each of them processes events for objects created (and owned) by their thread.


My intent is to have two separate threads operating independently, one for the server and one for the client.
This might not be necessary, you know...


Each needs to handle messages and events without conflicting with each other. Is that possible using the "client launches the server in a separate thread" approach, or do I need to code the two entities as separate apps and execute them independently of each other (like the fortune server/client examples)?

You can do it in a single processes. It is likely you can do it even in a single thread with a single event loop.

jacek
22nd August 2008, 01:31
My client acts like it's not getting any time (graphics don't refresh, timed messages never disappear, etc.).
Are you sure you start a separate thread?

smahnken
22nd August 2008, 04:55
I guess I'm not expert enough to say that I'm certain, but I'm pretty sure. Perhaps you can provide a sanity check for me...

The server class is declared like so:

class Xorbz_Game : public QThread
{
Q_OBJECT

public:
Xorbz_Game( class Xorbz* parent );
~Xorbz_Game( void );

etc...

The client (main app) instantiates the server like so:


// Instantiate a new game engine
currentGame = new Xorbz_Game( this );

After the client sets a few things in the server via member functions, it starts things up like this:


// Start the game running
currentGame->start();


Anything look amiss?

jacek
22nd August 2008, 08:49
Anything look amiss?
No, you must block the main event loop in some other way. Do you have any loops in your GUI code?

smahnken
22nd August 2008, 21:59
No loops in my GUI code, but maybe I'm chasing the wrong thing. I'm probably doing something wrong with the graphics. I found that if I resize the window, or minimize/restore it, the graphics do update, but only while I'm resizing.

The whole project is a migration effort from the QT 3.x series, in which the code base used the QCanvas and QPixmapArray stuff. I'm now trying to establish the same functionality with the QT 4.x series.

I'll go poke around (and read) some more with the new graphics structure. I know there's the whole update() thing, but there's a good chance I've got something wrong there. I'll start a new discussion thread once I've got some substantiated questions.

Thanks again for your help!

wysota
24th August 2008, 18:13
Are you sure you need threads at all?