Pthreads Programming: A Posix Standard for Better Multiprocessingby Dick Buttlar, Jacqueline Farrell, Bradford Nichols, Jacqueline Proulx Farrell
Computers are just as busy as the rest of us nowadays. They have lots of tasks to do at once, and need some cleverness to get them all done at the same time.That's why threads are seen more and more often as a new model for programming. Threads have been available for some time. The Mach operating system, the Distributed Computer Environment (DCE), and Windows NT
Computers are just as busy as the rest of us nowadays. They have lots of tasks to do at once, and need some cleverness to get them all done at the same time.That's why threads are seen more and more often as a new model for programming. Threads have been available for some time. The Mach operating system, the Distributed Computer Environment (DCE), and Windows NT all feature threads.One advantage of most UNIX implementations, as well as DCE, is that they conform to a recently ratified POSIX standard (originally 1003.4a, now 1003.1c), which allows your programs to be portable between them. POSIX threads are commonly known as pthreads, after the word that starts all the names of the function calls. The standard is supported by Solaris, OSF/1, AIX, and several other UNIX-based operating systems.The idea behind threads programming is to have multiple tasks running concurrently within the same program. They can share a single CPU as processes do, or take advantage of multiple CPUs when available. In either case, they provide a clean way to divide the tasks of a program while sharing data.A window interface can read input on dozens of different buttons, each responsible for a separate task. A network server has to accept simultaneous calls from many clients, providing each with reasonable response time. A multiprocessor runs a number-crunching program on several CPUs at once, combining the results when all are done. All these kinds of applications can benefit from threads.In this book you will learn not only what the pthread calls are, but when it is a good idea to use threads and how to make them efficient (which is the whole reason for using threads in the first place). The authors delves into performance issues, comparing threads to processes, contrasting kernel threads to user threads, and showing how to measure speed. He also describes in a simple, clear manner what all the advanced features are for, and how threads interact with the rest of the UNIX system.Topics include:
- Basic design techniques
- Mutexes, conditions, and specialized synchronization techniques
- Scheduling, priorities, and other real-time issues
- UNIX libraries and re-entrant routines
- Debugging tips
- Measuring performance
- Special considerations for the Distributed Computing Environment (DCE)
- O'Reilly Media, Incorporated
- Publication date:
- Product dimensions:
- 7.00(w) x 9.19(h) x 0.59(d)
Read an Excerpt
Chapter 5: Pthreads and UNIXBecause operating systems are inherently designed to accommodate processes, not threads, system implementors must often bend tradition to introduce thread support. It's as if we were to discover one day that the sun did not orbit the earth, but that, in reality, the earth revolves around the sun. The process is no longer central to our operating system world. Whereas it used to schedule processes, our system now schedules threads-no minor feat because, to do so, it must rototill its internal data structures and reinvent some of its most basic notions. What's more, whereas it used to deliver signals to processes, it now must deliver signals to threads. How it selects the thread to which it delivers a given signal is yet another added complexity.
Further, the operating system has always allowed us to perform certain operations on processes that become riddles in the world of threads. If we now consider a process to be a sort of container for threads, and we recognize that all threads share their process's address space, what happens when one of these threads launches an operation that has processwide ramifications? Does a fork result in a copy of the entire process, including all existing threads? Does an exec wipe them out?
Finally, it's a rare, and probably not very useful, program that does not make a single library call. In the world of threads, what happens when a batch of threads in the same process call the same library function concurrently?. If this is the same library that existed in the pre-threaded implementation, there's a great chance that the library's static data will be overwritten at each successivecall. Thus, operating system vendors must address the behavior of libraries and system calls on top of everything else.
If a multithreaded program is to work correctly, it must rely on some well-defined, consistent behavior from the operating system. A little knowledge about the areas in which Pthreads and the operating system cross is well advised. In this chapter, we'll examine some ways in which Pthreads implementors attempt to make an operating system "thread friendly." We'll discuss:
Every program must respond to signal delivery in some way. Often a program must provide a routine that handles signals of various kinds. The Pthreads standard defines a method for threads to participate in signal handling that is compatible with the traditional method in which processes handle signals.
- Threadsafe libraries
Most system libraries maintain internal data for the currently executing process in internal data. To allow multiple threads from the same process to execute library routines simultaneously, library implementors must somehow protect this data from unsynchronized accesses by otherwise cooperative threads. Libraries that eliminate such race conditions are known as threadsafe libraries.
- Cancellation-safe library functions
If a thread is canceled while in the middle of a library call that is modifying a library's internal data, it may exit, leaving the data in an inconsistent or corrupted state. A library function in which a thread can be canceled safely is known as a cancellation-safe library routine.
- Blocking functions
One of the greatest benefits of threads programming relies on the expectation that, if one thread blocks while calling a library function, others may continue. The Pthreads standard defines exactly which library functions can block and when.
- Process management
Operating system support for threads complicates the standard operations that create and destroy processes (such as fork, exec, and exit). The Pthreads standard specifies the behavior of these operations in a multithreaded environment and requires backward compatibility for nonthreaded applications.
- Multiprocessor memory synchronization
Although more of an issue for platform machine architectures than for the operating system, threads must be assured that their views of shared data (including the states of mutexes and condition variables) are identical. This guarantee, as enforced by the Pthreads standard, must hold true whether the threads are running on a uniprocessor or on a multiprocessor.
Threads and Signals
The odd thing about signals in UNIX is that, although they're everywhere, their arrival-by its very nature-is always a bit of surprise. (Well, that's a bit of an exaggeration. When we're told that the furniture delivery person will be at our house between 9 a.m. and noon on Tuesday, we're prepared for a knock on the door-maybe at 9:15, maybe at 11:45, maybe even at 1:00, perhaps never. When the knock comes, we're ready with well-rehearsed instructions for the paths the delivery person must follow through our house to the place where the sofa will ultimately be placed. Some types of signals are like that; others are more like our smoke alarm before the furniture delivery person knocked it down.)
Nevertheless, our program may be interrupted at any time by a signal, and that signal may have been sent from any of a number of places. The system may send us a signal to report a hardware condition (a divide-by-zero or some other fault) or a software error. We can use various facilities so that the system sends us a signal when a particular event occurs, such as the expiration of a timer or the completion of an 1/0 operation. Other processes can send us a signal (and we can send one back) as a sort of low-level IPC mechanism. Even human beings can send us a signal by hitting CTRL-Z at the keyboard to suspend our program.
Most programs that accomplish serious work must have a built-in way of dealing with all of these signals flying around the system for all of these various purposes. This presented the Pthreads standard committee with three chief challenges:
- A thread should be able to send and receive signals, yet, to allow this, a Pthreads implementation cannot subvert a single-threaded process's ability to process signals in the way it always has.
- When a signal is delivered to a multithreaded process, a Pthreads implementation must select one of the threads to perform the required action.
- What can a thread do, while in a signal handler, that won't interfere with its mainline execution?
The committee met the first of these challenges by not changing the semantics of signal delivery to processes. In a Pthreads implementation, signals continue to be delivered to processes, not threads. The table that lists the process's reaction to...
Meet the Author
Dick Buttlar is a consulting writer in the UNIX Engineering Group at Digital Equipment Corporation, where he recently completed his stint as project leader for the Digital UNIX cluster documentation. He specializes in programming documentation -- both user-level and kernel -- and, in a former life, wrote the device driver documentation for the VMS operating system. A few years ago, he managed the initial planning of the corporate- wide documentation effort for Digital's Alpha processor. He's worked for Wang Laboratories, Recal/Redac, North American Technologies, and the American Trial Lawyers Association, among other places. He has a B.A. in English from Boston College and an M.A. in English from the University of Wisconsin at Madison.
Brad Nichols is a free-lance do-anything-computerish-for-a-buck kind of guy who works out of Milford, NH. He earned a Bachelor of Science degree in mechanical engineering from the University of New Hampshire in 1985 and a Master of Science degree from Worcester Polytechnic Institute (WPI) in 1991. He started his computer career working on very hard hardware (fuel pumps and valves). He worked his way up through the hardware layers into software on projects involving embedded avionics systems at Textron Lycomming and United Technologies Hamilton Standard Division. Brad left these jobs to learn more about AI at WPI, but instead caught the Mach fever, and was introduced to threads programming in UNIX. While at WPI he also worked on an OSF/1 performance project for the Open Software Foundation (OSF). After attending WPI, Brad taught training seminars to software developers on the Mach kernel interfaces. He then joined Digital Equipment Corporation to work on the port of the OSF's Distributed Computing Environment's Distributed File System (OSFDCEDFSDU for short) to Digital UNIX. Now, Brad is once again on his own and spends most of his time teaching software engineers about technologies with much shorter acronyms -- such as Pthreads.
Most Helpful Customer Reviews
See all customer reviews