Tricks of the Windows Game Programming Gurus:Algorithms, Data Structures, Memory Management, and Multithreading

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

#### Multithreading and DirectX

Now you know something about multithreading. The next question is how you can really use it in game programming and DirectX programs. Just do it—that’s all there is to it. Of course, you must make sure to use the multithreaded libraries rather than the single-threaded libraries when compiling. In addition, there are a lot of “critical section” problems that might arise when you’re mucking with DirectX resources.

Make sure that you use a global strategy for resources so that if more than one thread accesses a resource, nothing will blow up. For example, let’s say that one thread locks a surface, and then another thread executes and tries to lock the same surface. This will cause a problem. These kinds of problems can be solved using sempahores, mutexes, and critical sections. I don’t have time to cover any of these, but you can always pick up a good book on the subject, like Multithreading Applications in Win32 by Jim Beveridge and Robert Weiner, published by Addison Wesley. This is the best book I’ve seen on the topic.

To implement these types of resource management applications and to share threads properly, you simply create variables that track if another thread is using the resource. Then, any thread that wants a resource that other thread might be using tests this variable before mucking with it. Of course, this can also be a problem unless the variable can be tested and changed atomically, because you could be halfway through changing a variable and another thread could gain control.

You can minimize this by making these variables of the type `volatile`, which tells the compiler not to make memory copies, for one thing. However, in the end you’ll have to use semaphores (a simple counter like the global variable, but implemented with atomic code in assembly that can’t be interrupted), mutexes (allows only one thread to enter a critical section; a binary semaphore), critical sections (sections that you indicate to the compiler with Win32 calls that are only supposed to allow one thread at a time), and so forth, so read up on them. On the other hand, if each thread is fairly independent in what it does, you won’t have to worry about this stuff as much.

For an example of a DirectX application that uses threads, check out `DEMO11_10.CPP[vbar]EXE`. It creates a number of alien BOBs (blitter objects) and moves them around in the mainline. Also, an addition thread is created to animate the colors of the BOBs. This is a very simple and safe example of multithreading. There aren’t many problems with having another thread animate colors. Make sure to link with all the DirectX `.LIB` files

However, if you had many threads all calling the same functions, the problem of reentrancy would come into play. Functions that are reentrant need to have state information and can’t use globals that can be corrupted by preemptive threads coming in and out of the code.

In addition, if you use threads to animate the DirectX blitter objects themselves, surface contingency, timing, and synchronization will really wreak havoc on your code. I suggest restricting the use of threads to processes that are for the most part independent of others, exist in their own “state space,” and don’t have to run at a precise rate.

#### Advanced Multithreading

Well, this is a good place to stop because the next set of topics have to do with race conditions, deadlocks, critical sections, mutexes, semaphores, and really big headaches. All of these things (except the last one) help you write multithreaded programs that don’t step on each other. However, even without knowing about them, you can still accomplish a lot of safe multithreaded programming just by using common sense and remembering that any thread can interrupt any other thread. Just be careful with how your threads access shared data structures.

Try to do everything as automatically as possible. Make sure that one thread doesn’t alter a variable and then another thread uses this half-altered version! Also, there were a few function calls left out of this chapter that are fairly basic, such as `ExitThread()` and `GetThreadExitCode()`, but they’re fairly simple to understand and you can look them up in your favorite API bible.

### Summary

This has been a refreshing chapter, don’t you think? :) Nothing too technical; just a potpourri of invaluable information in a scintillating format. Okay, I think I’ve had one too many Power Bars! Seriously, though, we’ve covered a lot of ground: data structures, memory management, recursion, analysis, fixed-point math, and multithreading.

These things may not seem to be game-related, but they are. To make a game, you need to know every single topic in programming—it’s that complex! Anyway, go out and rent 2001: A Space Odyssey, because it’s time to talk about artificial intelligence…

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.