Chapter Fourteen Multiple Threading Applications

A program of any complexity at all is a maze of instructions that loop and branch and are full of forks, jumps, and returns. The processor makes decisions as the program runs, and each decision leads through a different set of instructions. Each time the program executes, the processor follows a different path from start to finish. When Theseus fought the Minotaur, he marked his way through the labyrinth by unwinding a thread behind him. When a program wants to do several things at once, it creates objects called threads, and each thread winds its own way through the program’s code.

Another way to look at it is to say that threads let a program be in two places at once. The system keeps a list of all the threads and cycles through them, giving each a slice of time on the processor. When a time slice ends, the system records the current CPU register values in the thread object, including a pointer to whatever instruction the thread was about to execute. The system then selects another thread, restores its CPU registers, and resumes execution wherever the thread last left off. A thread marks a location in the program, and by marking several locations with different threads, the program effectively clones itself and seems to execute in many places at the same time.

This is how threads work in a single-CPU system, which is what most of us are still relying on today. However, the wave of the future is multiple-CPU systems—desktop systems with as many as four CPUs and a multiprocessor environment. Here is where threads really shine. With multiple processors to handle tasking, the system is able to allocate different threads to different processors; it spreads the load across several CPUs. Each CPU can execute separate tasks simultaneously for different threads.

One area where this will be particularly advantageous is 3-D modeling and image processing, where different threads can share aspects of creating an image among two or more CPUs. Another area is in Windows itself, which must handle a variety of tasks of its own in addition to the tasks of the applications it is supporting. Again, a workload shared among several processors makes faster progress than sharing time-slices on a single processor.

This chapter begins with a conceptual introduction to threads, then surveys the commands for using threads, and finishes with a sample program demonstrating threads. By the end of this chapter, you will understand when and how to create threads in your programs, how to manage them while they run, and how to synchronize them so they don’t interfere with each other. Mutexes, semaphores, events, and critical sections will hold no more mysteries for you.

© 1998 SYBEX Inc. All rights reserved.