Race Conditions
2.3.1 Race Conditions
In some operating systems, processes that are working together may share some common storage that each one can read and write. The shared storage may be in main memory (possibly in a kernel data structure) or it may be a shared file; the location of the shared memory does not change the nature of the communication or the problems that arise. To see how interprocess communication works in practice, let us now consider a simple but common example: a print spooler. When a process
CHAP. 2 wants to print a file, it enters the file name in a special spooler directory. Another
PROCESSES AND THREADS
process, the printer daemon, periodically checks to see if there are any files to be printed, and if there are, it prints them and then removes their names from the di- rectory.
Imagine that our spooler directory has a very large number of slots, numbered
0, 1, 2, ..., each one capable of holding a file name. Also imagine that there are two shared variables, out, which points to the next file to be printed, and in, which points to the next free slot in the directory. These two variables might well be kept in a two-word file available to all processes. At a certain instant, slots 0 to 3 are empty (the files have already been printed) and slots 4 to 6 are full (with the names of files queued for printing). More or less simultaneously, processes A and B decide they want to queue a file for printing. This situation is shown in Fig. 2-21.
Spooler directory
out = 4 Process A
4 abc
5 prog.c 6 prog.n
7 in = 7
Process B
Figure 2-21. Tw o processes want to access shared memory at the same time.
In jurisdictions where Murphy’s law † is applicable, the following could hap- pen. Process A reads in and stores the value, 7, in a local variable called next free slot. Just then a clock interrupt occurs and the CPU decides that proc- ess A has run long enough, so it switches to process B. Process B also reads in and also gets a 7. It, too, stores it in its local variable next free slot. At this instant both processes think that the next available slot is 7.
Process B now continues to run. It stores the name of its file in slot 7 and updates in to be an 8. Then it goes off and does other things. Eventually, process A runs again, starting from the place it left off. It looks at next free slot, finds a 7 there, and writes its file name in slot 7, erasing the name that process B just put there. Then it computes next free slot + 1, which is 8, and sets in to 8. The spooler directory is now internally consistent, so the printer dae- mon will not notice anything wrong, but process B will never receive any output. User B will hang around the printer for years, wistfully hoping for output that
† If something can go wrong, it will.
SEC. 2.3
INTERPROCESS COMMUNICATION
never comes. Situations like this, where two or more processes are reading or writ- ing some shared data and the final result depends on who runs precisely when, are called race conditions. Debugging programs containing race conditions is no fun at all. The results of most test runs are fine, but once in a blue moon something weird and unexplained happens. Unfortunately, with increasing parallelism due to increasing numbers of cores, race condition are becoming more common.
Parts
» The Second Generation (1955–65): Transistors and Batch Systems
» The Third Generation (1965–1980): ICs and Multiprogramming
» The Fourth Generation (1980–Present): Personal Computers
» System Calls for Process Management
» System Calls for Directory Management
» RESEARCH ON OPERATING SYSTEMS
» Implementing Threads in User Space
» Implementing Threads in the Kernel
» Making Single-Threaded Code Multithreaded
» Mutual Exclusion with Busy Waiting
» Avoiding Locks: Read-Copy-Update
» Scheduling in Interactive Systems
» Scheduling in Real-Time Systems
» The Dining Philosophers Problem
» The Readers and Writers Problem
» The Notion of an Address Space
» Page Tables for Large Memories
» DESIGN ISSUES FOR PAGING SYSTEMS
» Segmentation with Paging: MULTICS
» Segmentation with Paging: The Intel x86
» An Example Program Using File-System Calls
» Device-Independent I/O Software
» Disk Arm Scheduling Algorithms
» Preemptable and Nonpreemptable Resources
» Deadlock Detection with One Resource of Each Type
» Deadlock Detection with Multiple Resources of Each Type
» The Banker’s Algorithm for Multiple Resources
» REQUIREMENTS FOR VIRTUALIZATION
» TYPE 1 AND TYPE 2 HYPERVISORS
» TECHNIQUES FOR EFFICIENT VIRTUALIZATION
» ARE HYPERVISORS MICROKERNELS DONE RIGHT?
» Challenges in Bringing Virtualization to the x86
» VMware Workstation: Solution Overview
» ESX Server: VMware’s type 1 Hypervisor
» Multiprocessor Operating System Types
» Multiprocessor Synchronization
» Low-Level Communication Software
» User-Level Communication Software
» Network Services and Protocols
» File-System-Based Middleware
» Coordination-Based Middleware
» Authentication Using a Physical Object
» Authentication Using Biometrics
» Antivirus and Anti-Antivirus Techniques
» Model-Based Intrusion Detection
» Process-Management System Calls in Linux
» Implementation of Processes and Threads in Linux
» Implementation of the Linux File System
» NFS: The Network File System
» HISTORY OF WINDOWS THROUGH WINDOWS 8.1
» The Native NT Application Programming Interface
» The Win32 Application Programming Interface
» Implementation of the Object Manager
» Subsystems, DLLs, and User-Mode Services
» Job, Process, Thread, and Fiber Management API Calls
» Implementation of Processes and Threads
» Memory-Management System Calls
» Implementation of Memory Management
» Why Is It Hard to Design an Operating System?
» Static vs. Dynamic Structures
» Synchronous vs. Asynchronous Communication
» TRENDS IN OPERATING SYSTEM DESIGN
» SUGGESTIONS FOR FURTHER READING
Show more