Add Book to My BookshelfPurchase This Book Online

Chapter 5 - Pthreads and UNIX

Pthreads Programming
Bradford Nichols, Dick Buttlar and Jacqueline Proulx Farrell
 Copyright 1996 O'Reilly & Associates, Inc.

Thread-Blocking Library Functions and System Calls
The key reason for using threads lies in the convenience and efficiency of letting one thread block on an I/O operation or synchronization call while others continue performing the useful work of your program. With this in mind, we've assumed from the start of the book that each time a thread makes a system call that blocks, only the thread itself is stalled, not the entire process. We haven't been entirely up front with you. Our assumption's a bit presumptuous. 
In a nonthreaded program, system calls that perform file I/O (like open, read, and write) or synchronize processes (wait) block their callers until the requested operation completes. You can avoid some blocking on a file operation by passing the POSIX O_NONBLOCK flag or the BSD O_NDELAY flag to the file's open call, or the FIONBIO flag to an ioctl call to the file. When a process issues a subsequent read or write call on that file, it would receive notification of I/O completion through a SIGIO signal. 
Process blocking is fine when a process has a single execution state, but it subverts the whole purpose of threads. A system call that blocks a process would block all of our threads, and we'd lose all of the advantages of concurrency until the system call completes. If we used nonblocking calls as described previously, we'd need to add synchronization code to our threads to wait for the completion signal. 
Fortunately, the Pthreads standard requires that vendors implement many blocking POSIX.1 calls so that they suspend only the calling thread and not the entire process. (The nonblocking behavior of the I/O calls remains the same.) They include: 
fcntl
open
pause
read
sigsuspend
sleep
wait
waitpid
write
What if a blocking call supplied by your system is not listed here? If you must use the call, you have a few options: 
 You may get lucky and discover your implementation has implemented the code as nonblocking. So much for portability! 
 Let your entire application stall while the call blocks. (Think of it as a rock-climbing expedition in which your more athletically adept friends stop to wait for you as you haul yourself up behind them.) 
 Fork another process to do the call. (It works, but using threads was supposed to eliminate the need for you to do this.) 
 Use any available nonblocking alternative. Here, you avoid blocking the process, but you'll need to add explicit synchronization to your thread so it can retrieve the results of the call. 

Previous SectionNext Section
Books24x7.com, Inc 2000   Feedback