Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [A5] Threading a game

Credits go to Edgar Reynaldo and Thomas Fjellstrom for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
[A5] Threading a game
RPG Hacker
Member #12,492
January 2011
avatar

I also have a threading related question. Guess I'll just ask it here:

When should I use mutexes? I know you're supposed to use them when, for example, accessing linked lists or something similiar. However, somewhere I read that you have to use them even when you're just using shared variables or even shared functions. Is that correct? I can hardly imagine, because that would surely make a lot of mutexes.

Also can someone here recommend good thread setups? Right now I have one thread for the logic loop and one thread for the screen loop. For a simple 2D platformer like I'm making, I guess, that's alright, although I'm only using up to two cores, but generally speaking: Is there any recommended thread setup for games? How many threads should you use and what for?

Matthew Leverton
Supreme Loser
January 1999
avatar

J-Gamer said:

Are allegro calls thread-safe?

Yes and no. It's not documented, and I'm not even sure which calls are and aren't. Other than events, you should basically assume the calls are not thread safe.

Guess I'll just ask it here:

Don't hijack other people's threads.

RPG Hacker
Member #12,492
January 2011
avatar

Don't hijack other people's threads.

I don't see the problem, as it's perfectly related to the thread's title and can most likely help the thread creator as well. If you still think my post doesn't fit then tell me and I'll create a new one.

J-Gamer
Member #12,491
January 2011
avatar

To answer your question:
AFAIK the only time you need to use mutexes is when there's the possibility two threads will try to access the same variable at the same time. That's the whole point of mutexes and conditions.
I didn't know that you need them when accessing lists etc... seems strange.

EDIT: about thread setup, I was thinking of doing it this way:
Main thread where the game logic is executed
User input thread
AI thread
Render thread

The UI and AI threads send costum events to the main thread, which I explained before.

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

RPG Hacker
Member #12,492
January 2011
avatar

Thanks for the response.

J-Gamer said:

AFAIK the only time you need to use mutexes is when there's the possibility two threads will try to access the same variable at the same time. That's the whole point of mutexes and conditions.
I didn't know that you need them when accessing lists etc... seems strange.

Well, if accessing linked lists (talking about shared lists here of course) without a mutex, one thread could delete an element another thread is using, causing it to be deadlocked, so it seems logical to me to use a mutex in this situation. I just don't know if using regular shared variables necessarily requires mutexes. Is it that critical if two threads access a variable at the same time? Sure: When using a variable multiple times in a thread it may be a good idea to make a copy of it, anyways, just to prevent it from being changed mid-thread, but let's assume we have a variable that the logic thread writes to, while the render thread only reads it. Can it have critical effects if both threads access the variable at the same time, anyways?

J-Gamer
Member #12,491
January 2011
avatar

If the render thread asks for it while the logic thread is changing it, yes(certainly for larger variables). You could get garbage values because the processor is halfway trough its writing process.

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

RPG Hacker
Member #12,492
January 2011
avatar

I see. I guess it's "rather be safe than sorry" then and I shouldn't hesitate to use mutexes. Thanks!

ImLeftFooted
Member #3,935
October 2003
avatar

You can also go too crazy using mutexes (mutices?[1]). Balance is key.

I'm working on solving a race condition[2] at the moment, which can happen with overuse of mutexes. In my particular case there is design flaw causing the mutex to try to lock itself twice. For instance:

#SelectExpand
1int theOracle(); 2 3int theAdvisersBuddy() 4{ 5 int r = 5; 6 if(notSoSure) 7 r += theOracle(); 8 return r; 9} 10 11int adviser() 12{ 13 int r = 13; 14 r += theAdvisersBuddy(); 15} 16 17int theOracle() 18{ 19 mutex.lock(); 20 int r = rand()%5; 21 r += adviser(); 22 mutex.unlock(); 23 return r; 24} 25 26printf("The oracle has spoken: %d", theOracle());

In this case the oracle must consult his adviser to give his answer. Little does the Oracle know, the adviser has a buddy. The adviser always consults his buddy before telling the oracle what to do. When the buddy is unsure what to give the adviser, he consults the oracle.

Here is the backtrace (flipped for learner's sake):

  1. printf() <- The output statement

  2. theOracle() => the mutex is now locked!

  3. adviser() <- the oracle is consulting his adviser

  4. theAdvisersBuddy() <- the adviser is consulting his buddy

  5. theOracle() => The mutex is locked a second time!

Since you can't lock a mutex twice, the program will freeze on the line 'mutex.lock()' inside theOracle.

RPG Hacker
Member #12,492
January 2011
avatar

Can't recursive mutexes do that (assuming all that code is running on one thread)?

ImLeftFooted
Member #3,935
October 2003
avatar

I suppose that's true. My example is not ideal then.

 1   2 


Go to: