Beginning win32 multithreading

In an attempt to understand windows multithreading a little more thoroughly, I’ve decided to write about the simple concepts associated with multithreading. This is mainly to clarify it in my own head but maybe it will help someone else out too. If any of this information is wrong, don’t yell at me.:-)Please just post a comment and I’ll look into it and/or fix it. So here we go.

Thread: I’m not going to define a thread. Just know that a thread is a kernel object, which means that when a thread finishes executing, it gets signaled. If you use “WaitForSingleObject();” for example to wait for it to finish executing, it is safer and doesn’t eat up CPU time like a spin lock would.

Signaled: Kernel objects get signaled (threads, mutexes, etc.). When a kernel object gets signaled, “WaitForSingleObject()” wakes up. The same goes for other “Wait*()” functions. In the case of threads: running = nonsignaled, when a thread terminates = signaled.

Atomic Operation: A single operation that the processor can not perform a context switch in between.

Context Switch: When the processor halts execution of a thread, and then continues executing another thread from where it left off previously. The cause of race conditions when multithreading, but a necessary feature on processors.

Spin Lock: Eats CPU time, not atomic. Basically the predecessor to critical sections. Basically a “for” loop that waits around until a thread returns. This is the worst way to do multithreading, don’t use spin locks at all.

Race Condition: The easiest way to conceptualize a race condition is to think of it this way: A thread writes data and soon after, another thread blindly overwrites the data that was just written by the first thread. Critical Sections resolve this.

Critical Section: If you only have one resource that needs sharing between multiple threads, you use a “Critical Section.” Critical sections are not kernel objects and prevent race conditions between multiple threads. The reason you use critical sections is to make certain areas of your code / data atomic so that a context switch doesn’t fowl up your data. Note: You can specify different areas of your code as the same critical section.

Mutex: If you have multiple resources that need to be shared among threads, you do NOT use a critical section. This can result in a dead lock where one thread waits for the other thread to release a resource, but that thread is waiting on the first thread to release a resource it needs, so both end up waiting forever. So instead you use a mutex. A mutex is a kernel object and can be shared among threads as well as processes. Basically, a mutex says: “Execute this code if both (or however many the mutex was defined with) resources are available.” If that requirement isn’t satisfied, then the code isn’t run. For example: If only one resource was available but the mutex was defined for two resources, then the code would not run.

Note: Mutexes introduce race conditions now, the very thing that critical sections fixed. Also, it’s worth noting that you can still get a dead lock with mutexes if you use “WaitForSingleObject().” Instead, you must use “WaitForMultipleObjects()” to avoid dead locks.

Win32 functions associated with multithreading
General Win32 Thread Functions: You can look up the parameters yourself on msdn.
CreateThread();
GetExitCodeThread();
ExitThread();
WaitForSingleObject();
WaitForMultipleObjects();
MsgWaitForMultipleObjects();

Critical Section: Sharing one resource
InitializeCriticalSection();
DeleteCriticalSection();
EnterCriticalSection();
LeaveCriticalSection();

Mutex: Sharing multiple resources
CreateMutex();
OpenMutex();
WaitForSingleObject();
WaitForMultipleObjects();
MsgWaitForMultipleObjects();
ReleaseMutex();
CloseHandle();

Sundown Cerose

Description: A fast-paced comic book style 3D isometric based action/adventure game where the player must battle hordes of minions in order to save the galaxy.


Gameplay video footage of Sundown Cerose.

Position: Technical Director

Date: 2008 – 2009

Accomplishments:

  • Designed and coded the input, using DirectInput, scene management system, using TinyXML, physics, collision detection, and the engine framework to allow for dynamic object interactivity.
  • Implemented all of the required features by utilizing C/C++, the Win32 API, DirectX, C/C++ Standard Libraries, and the STL to ensure a robust framework on the Windows PC platform.
  • Worked closely with the designer and the producer to successfully implement the game’s required features before the preceded milestones.
  • Engineered a component based design using Object Oriented Programming principles to allow for versatility in the engine framework.
  • Assisted in the core design of “Sundown Cerose” in order to plan the development of a dynamic and robust engine architecture that would meet the designs requirements.
  • Designed and Implemented the level editor

Platform: PC

Requirements: Windows XP, DirectX 9 compatible graphics card, 512 MB RAM, 1.6 GHz Processor, Vertex/Pixel shaders 2.0 or greater.

Controls: Move: W,A,S,D
Aim: Mouse
Shoot fireball:Left mouse button
Flame thrower: Right mouse button

Screen Shots:

The flame thrower in action.

The player was hit and is now running away.

The player shooting fireballs.

The player charging at the enemies.