MODERN MULTITHREADING

Similar documents
Real-Time Optimization by Extremum-Seeking Control

COMPONENT-ORIENTED PROGRAMMING

TASK SCHEDULING FOR PARALLEL SYSTEMS

LEGITIMATE APPLICATIONS OF PEER-TO-PEER NETWORKS DINESH C. VERMA IBM T. J. Watson Research Center A JOHN WILEY & SONS, INC., PUBLICATION

Relational Database Index Design and the Optimizers

LEGITIMATE APPLICATIONS OF PEER-TO-PEER NETWORKS

Microprocessor Theory

HASHING IN COMPUTER SCIENCE FIFTY YEARS OF SLICING AND DICING

DIFFERENTIAL EQUATION ANALYSIS IN BIOMEDICAL SCIENCE AND ENGINEERING

COSO Enterprise Risk Management

Modern Experimental Design

Algorithms and Parallel Computing

Practical Database Programming with Visual Basic.NET

MODERN MULTITHREADING

IP MULTICAST WITH APPLICATIONS TO IPTV AND MOBILE DVB-H

Recall from Chapter 1 that a data race is a failure to correctly implement critical sections for non-atomic shared variable accesses.

OVER 750 QUESTIONS AND 55 TASK-BASED SIMULATIONS! CPA EXAM REVIEW. Auditing and Attestation. O. Ray Whittington, CPA, PhD Patrick R.

Agile Database Techniques Effective Strategies for the Agile Software Developer. Scott W. Ambler

7 Windows Tweaks. A Comprehensive Guide to Customizing, Increasing Performance, and Securing Microsoft Windows 7. Steve Sinchak


Study Guide. Robert Schmidt Dane Charlton

Synchronization. CS 475, Spring 2018 Concurrent & Distributed Systems

Linux Command Line and Shell Scripting Bible. Third Edtion

Multi-Core Programming

CS 571 Operating Systems. Midterm Review. Angelos Stavrou, George Mason University

Mastering UNIX Shell Scripting

Read & Download (PDF Kindle) Modern Multithreading: Implementing, Testing, And Debugging Multithreaded Java And C++/Pthreads/Win32 Programs

PROCESSES & THREADS. Charles Abzug, Ph.D. Department of Computer Science James Madison University Harrisonburg, VA Charles Abzug

Outline: SYN-sequences for distributed Java programs that use classes TCPSender and TCPMailbox tracing, replay and feasibility

CSE Traditional Operating Systems deal with typical system software designed to be:

THE ARCHITECTURE OF COMPUTER HARDWARE, SYSTEM SOFTWARE, AND NETWORKING

Chapter 5 Concurrency: Mutual Exclusion and Synchronization

1. Introduction to Concurrent Programming

Beginning Transact-SQL with SQL Server 2000 and Paul Turley with Dan Wood

Oracle PL/SQL. DUMmIES. by Michael Rosenblum and Dr. Paul Dorsey FOR

Operating Systems. Designed and Presented by Dr. Ayman Elshenawy Elsefy

Join the p2p.wrox.com. Wrox Programmer to Programmer. Beginning PHP 5.3. Matt Doyle

Module 6: Process Synchronization. Operating System Concepts with Java 8 th Edition

Professional ASP.NET 2.0 Databases. Thiru Thangarathinam

4.10 Tracing and Replay for Monitors

Magical Math G ROOVY G EOMETRY. Games and Activities That Make Math Easy and Fun. Lynette Long. John Wiley & Sons, Inc.

Linux Command Line and Shell Scripting Bible

Chapter 5 Concurrency: Mutual Exclusion. and. Synchronization. Operating Systems: Internals. and. Design Principles

Beginning Web Programming with HTML, XHTML, and CSS. Second Edition. Jon Duckett

Let M be a monitor that is implemented using one of the monitor toolboxes.

ENGR 3950U / CSCI 3020U UOIT, Fall 2012 Quiz on Process Synchronization SOLUTIONS

Synchronization COMPSCI 386

More Synchronization; Concurrency in Java. CS 475, Spring 2018 Concurrent & Distributed Systems

FUNDAMENTALS OF COMPUTER ORGANIZATION AND ARCHITECTURE

Chapter 2 Processes and Threads

Concurrency. Chapter 5

EI 338: Computer Systems Engineering (Operating Systems & Computer Architecture)

Synchronization for Concurrent Tasks

Process Synchronization

Concurrent & Distributed Systems Supervision Exercises

Lecture Topics. Announcements. Today: Concurrency (Stallings, chapter , 5.7) Next: Exam #1. Self-Study Exercise #5. Project #3 (due 9/28)

Synchronization Principles

Concurrency: Mutual Exclusion and

DATABASE DESIGN AND DEVELOPMENT

7. Testing and Debugging Concurrent Programs

COMPUTING FOR NUMERICAL METHODS USING VISUAL C++

Implementing Security and Tokens: Current Standards, Tools, and Practices

Concept of a process

Introduction to Parallel Programming Part 4 Confronting Race Conditions

Process Synchronization: Semaphores. CSSE 332 Operating Systems Rose-Hulman Institute of Technology

Process Synchronization. Mehdi Kargahi School of ECE University of Tehran Spring 2008

Semaphore. Originally called P() and V() wait (S) { while S <= 0 ; // no-op S--; } signal (S) { S++; }

Process Synchronization(2)

Process Synchronization

Application Programming

Deadlock. Concurrency: Deadlock and Starvation. Reusable Resources

IT 540 Operating Systems ECE519 Advanced Operating Systems

COMPUTATIONAL DYNAMICS

Networking. 11th Edition. by Doug Lowe

Process Synchronization(2)

Concurrent, Real-Time and Distributed Programming in Java

J2EE TM Best Practices Java TM Design Patterns, Automation, and Performance

CSI3131 Final Exam Review

Synchronization Possibilities and Features in Java

Deadlock. Disclaimer: some slides are adopted from Dr. Kulkarni s and book authors slides with permission 1

Concurrency pros and cons. Concurrent Programming Problems. Linked list example. Linked list example. Mutual Exclusion. Concurrency is good for users

Interprocess Communication By: Kaushik Vaghani

Syllabus CSCI 405 Operating Systems Fall 2018

Models of concurrency & synchronization algorithms

Operating Systems. Lecture 4 - Concurrency and Synchronization. Master of Computer Science PUF - Hồ Chí Minh 2016/2017

Exploiting Distributed Resources in Wireless, Mobile and Social Networks Frank H. P. Fitzek and Marcos D. Katz

Chapter 6: Synchronization. Operating System Concepts 8 th Edition,

Fundamentals of Operating Systems. Fifth Edition

Midterm Exam. October 20th, Thursday NSC

PHP & MySQL. Learn to: Janet Valade. Making Everything Easier! 4th Edition. Create well-formed PHP code that s compliant with PHP 4, 5, and 6

Chapter 5: Process Synchronization. Operating System Concepts 9 th Edition

To Everyone... iii To Educators... v To Students... vi Acknowledgments... vii Final Words... ix References... x. 1 ADialogueontheBook 1

The Internet of Things

OS06: Monitors in Java

Lesson 6: Process Synchronization

1 OBJECT-ORIENTED PROGRAMMING 1

What is the Race Condition? And what is its solution? What is a critical section? And what is the critical section problem?

Cloud Phone Systems. Andrew Moore. Making Everything Easier! Nextiva Special Edition. Learn:

Process Synchronization(2)

iwork DUMmIES 2ND EDITION FOR

Transcription:

MODERN MULTITHREADING Implementing, Testing, and Debugging Multithreaded Java and C++/Pthreads/Win32 Programs RICHARD H. CARVER KUO-CHUNG TAI A JOHN WILEY & SONS, INC., PUBLICATION

MODERN MULTITHREADING

MODERN MULTITHREADING Implementing, Testing, and Debugging Multithreaded Java and C++/Pthreads/Win32 Programs RICHARD H. CARVER KUO-CHUNG TAI A JOHN WILEY & SONS, INC., PUBLICATION

Copyright 2006 by John Wiley & Sons, Inc. All rights reserved. Published by John Wiley & Sons, Inc., Hoboken, New Jersey. Published simultaneously in Canada. No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning, or otherwise, except as permitted under Section 107 or 108 of the 1976 United States Copyright Act, without either the prior written permission of the Publisher, or authorization through payment of the appropriate per-copy fee to the Copyright Clearance Center, Inc., 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 750-4470, or on the web at www.copyright.com. Requests to the Publisher for permission should be addressed to the Permissions Department, John Wiley & Sons, Inc., 111 River Street, Hoboken, NJ 07030, (201) 748-6011, fax (201) 748-6008, or online at http://www.wiley.com/go/permission. Limit of Liability/Disclaimer of Warranty: While the publisher and author have used their best efforts in preparing this book, they make no representations or warranties with respect to the accuracy or completeness of the contents of this book and specifically disclaim any implied warranties of merchantability or fitness for a particular purpose. No warranty may be created or extended by sales representatives or written sales materials. The advice and strategies contained herein may not be suitable for your situation. You should consult with a professional where appropriate. Neither the publisher nor author shall be liable for any loss of profit or any other commercial damages, including but not limited to special, incidental, consequential, or other damages. For general information on our other products and services or for technical support, please contact our Customer Care Department within the United States at (800) 762-2974, outside the United States at (317) 572-3993 or fax (317) 572-4002. Wiley also publishes its books in a variety of electronic formats. Some content that appears in print may not be available in electronic formats. For more information about Wiley products, visit our web site at www.wiley.com. Library of Congress Cataloging-in-Publication Data: Carver, Richard H., 1960 Modern multithreading: implementing, testing, and debugging multithreaded Java and C++/Pthreads/Win32 programs / by Richard H. Carver and Kuo-Chung Tai. p. cm. Includes bibliographical references and index. ISBN-13 978-0-471-72504-6 (paper) ISBN-10 0-471-72504-8 (paper) 1. Parallel programming (Computer science) 2. Threads (Computer programs) I. Tai, Kuo-Chung. II. Title. QA76.642.C38 2006 005.1 1 dc22 2005045775 Printed in the United States of America. 10987654321

CONTENTS Preface xi 1 Introduction to Concurrent Programming 1 1.1 Processes and Threads: An Operating System s View, 1 1.2 Advantages of Multithreading, 3 1.3 Threads in Java, 4 1.4 Threads in Win32, 6 1.5 Pthreads, 9 1.6 C++ Thread Class, 14 1.6.1 C++ Class Thread for Win32, 14 1.6.2 C++ Class Thread for Pthreads, 19 1.7 Thread Communication, 19 1.7.1 Nondeterministic Execution Behavior, 23 1.7.2 Atomic Actions, 25 1.8 Testing and Debugging Multithreaded Programs, 29 1.8.1 Problems and Issues, 30 1.8.2 Class TDThread for Testing and Debugging, 34 1.8.3 Tracing and Replaying Executions with Class Template sharedvariable<>, 37 1.9 Thread Synchronization, 38 Further Reading, 38 References, 39 Exercises, 41 v

vi CONTENTS 2 The Critical Section Problem 46 2.1 Software Solutions to the Two-Thread Critical Section Problem, 47 2.1.1 Incorrect Solution 1, 48 2.1.2 Incorrect Solution 2, 49 2.1.3 Incorrect Solution 3, 50 2.1.4 Peterson s Algorithm, 52 2.1.5 Using the volatile Modifier, 53 2.2 Ticket-Based Solutions to the n-thread Critical Section Problem, 54 2.2.1 Ticket Algorithm, 54 2.2.2 Bakery Algorithm, 56 2.3 Hardware Solutions to the n-thread Critical Section Problem, 58 2.3.1 Partial Solution, 59 2.3.2 Complete Solution, 59 2.3.3 Note on Busy-Waiting, 60 2.4 Deadlock, Livelock, and Starvation, 62 2.4.1 Deadlock, 62 2.4.2 Livelock, 62 2.4.3 Starvation, 63 2.5 Tracing and Replay for Shared Variables, 64 2.5.1 ReadWrite-Sequences, 65 2.5.2 Alternative Definition of ReadWrite-Sequences, 67 2.5.3 Tracing and Replaying ReadWrite-Sequences, 68 2.5.4 Class Template sharedvariable<>, 70 2.5.5 Putting It All Together, 71 2.5.6 Note on Shared Memory Consistency, 74 Further Reading, 77 References, 78 Exercises, 79 3 Semaphores and Locks 84 3.1 Counting Semaphores, 84 3.2 Using Semaphores, 86 3.2.1 Resource Allocation, 86 3.2.2 More Semaphore Patterns, 87 3.3 Binary Semaphores and Locks, 90 3.4 Implementing Semaphores, 92 3.4.1 Implementing P() and V(), 92 3.4.2 VP() Operation, 94 3.5 Semaphore-Based Solutions to Concurrent Programming Problems, 96 3.5.1 Event Ordering, 96

CONTENTS vii 3.5.2 Bounded Buffer, 96 3.5.3 Dining Philosophers, 98 3.5.4 Readers and Writers, 101 3.5.5 Simulating Counting Semaphores, 108 3.6 Semaphores and Locks in Java, 111 3.6.1 Class countingsemaphore, 111 3.6.2 Class mutexlock, 113 3.6.3 Class Semaphore, 115 3.6.4 Class ReentrantLock, 116 3.6.5 Example: Java Bounded Buffer, 116 3.7 Semaphores and Locks in Win32, 119 3.7.1 CRITICAL SECTION, 119 3.7.2 Mutex, 122 3.7.3 Semaphore, 124 3.7.4 Events, 132 3.7.5 Other Synchronization Functions, 134 3.7.6 Example: C++/Win32 Bounded Buffer, 134 3.8 Semaphores and Locks in Pthreads, 134 3.8.1 Mutex, 136 3.8.2 Semaphore, 137 3.9 Another Note on Shared Memory Consistency, 141 3.10 Tracing, Testing, and Replay for Semaphores and Locks, 143 3.10.1 Nondeterministic Testing with the Lockset Algorithm, 143 3.10.2 Simple SYN-Sequences for Semaphores and Locks, 146 3.10.3 Tracing and Replaying Simple PV-Sequences and LockUnlock-Sequences, 150 3.10.4 Deadlock Detection, 154 3.10.5 Reachability Testing for Semaphores and Locks, 157 3.10.6 Putting It All Together, 160 Further Reading, 163 References, 164 Exercises, 166 4 Monitors 177 4.1 Definition of Monitors, 178 4.1.1 Mutual Exclusion, 178 4.1.2 Condition Variables and SC Signaling, 178 4.2 Monitor-Based Solutions to Concurrent Programming Problems, 182 4.2.1 Simulating Counting Semaphores, 182 4.2.2 Simulating Binary Semaphores, 183 4.2.3 Dining Philosophers, 183 4.2.4 Readers and Writers, 187

viii CONTENTS 4.3 Monitors in Java, 187 4.3.1 Better countingsemaphore, 190 4.3.2 notify vs. notifyall, 191 4.3.3 Simulating Multiple Condition Variables, 194 4.4 Monitors in Pthreads, 194 4.4.1 Pthreads Condition Variables, 196 4.4.2 Condition Variables in J2SE 5.0, 196 4.5 Signaling Disciplines, 199 4.5.1 Signal-and-Urgent-Wait, 199 4.5.2 Signal-and-Exit, 202 4.5.3 Urgent-Signal-and-Continue, 204 4.5.4 Comparing SU and SC Signals, 204 4.6 Using Semaphores to Implement Monitors, 206 4.6.1 SC Signaling, 206 4.6.2 SU Signaling, 207 4.7 Monitor Toolbox for Java, 209 4.7.1 Toolbox for SC Signaling in Java, 210 4.7.2 Toolbox for SU Signaling in Java, 210 4.8 Monitor Toolbox for Win32/C++/Pthreads, 211 4.8.1 Toolbox for SC Signaling in C++/Win32/Pthreads, 213 4.8.2 Toolbox for SU Signaling in C++/Win32/Pthreads, 213 4.9 Nested Monitor Calls, 213 4.10 Tracing and Replay for Monitors, 217 4.10.1 Simple M-Sequences, 217 4.10.2 Tracing and Replaying Simple M-Sequences, 219 4.10.3 Other Approaches to Program Replay, 220 4.11 Testing Monitor-Based Programs, 222 4.11.1 M-Sequences, 222 4.11.2 Determining the Feasibility of an M-Sequence, 227 4.11.3 Determining the Feasibility of a Communication-Sequence, 233 4.11.4 Reachability Testing for Monitors, 233 4.11.5 Putting It All Together, 235 Further Reading, 243 References, 243 Exercises, 245 5 Message Passing 258 5.1 Channel Objects, 258 5.1.1 Channel Objects in Java, 259 5.1.2 Channel Objects in C++/Win32, 263 5.2 Rendezvous, 266 5.3 Selective Wait, 272

CONTENTS ix 5.4 Message-Based Solutions to Concurrent Programming Problems, 275 5.4.1 Readers and Writers, 275 5.4.2 Resource Allocation, 278 5.4.3 Simulating Counting Semaphores, 281 5.5 Tracing, Testing, and Replay for Message-Passing Programs, 281 5.5.1 SR-Sequences, 282 5.5.2 Simple SR-Sequences, 288 5.5.3 Determining the Feasibility of an SR-Sequence, 290 5.5.4 Deterministic Testing, 296 5.5.5 Reachability Testing for Message-Passing Programs, 297 5.5.6 Putting It All Together, 299 Further Reading, 304 References, 304 Exercises, 304 6 Message Passing in Distributed Programs 312 6.1 TCP Sockets, 312 6.1.1 Channel Reliability, 313 6.1.2 TCP Sockets in Java, 314 6.2 Java TCP Channel Classes, 317 6.2.1 Classes TCPSender and TCPMailbox, 318 6.2.2 Classes TCPSynchronousSender and TCPSynchronousMailbox, 326 6.2.3 Class TCPSelectableSynchronousMailbox, 328 6.3 Timestamps and Event Ordering, 329 6.3.1 Event-Ordering Problems, 330 6.3.2 Local Real-Time Clocks, 331 6.3.3 Global Real-Time Clocks, 332 6.3.4 Causality, 332 6.3.5 Integer Timestamps, 334 6.3.6 Vector Timestamps, 335 6.3.7 Timestamps for Programs Using Messages and Shared Variables, 339 6.4 Message-Based Solutions to Distributed Programming Problems, 341 6.4.1 Distributed Mutual Exclusion, 341 6.4.2 Distributed Readers and Writers, 346 6.4.3 Alternating Bit Protocol, 348 6.5 Testing and Debugging Distributed Programs, 353 6.5.1 Object-Based Sequences, 353 6.5.2 Simple Sequences, 362

x CONTENTS 6.5.3 Tracing, Testing, and Replaying CARC-Sequences and CSC-Sequences, 362 6.5.4 Putting It All Together, 369 6.5.5 Other Approaches to Replaying Distributed Programs, 371 Further Reading, 374 References, 375 Exercises, 376 7 Testing and Debugging Concurrent Programs 381 7.1 Synchronization Sequences of Concurrent Programs, 383 7.1.1 Complete Events vs. Simple Events, 383 7.1.2 Total Ordering vs. Partial Ordering, 386 7.2 Paths of Concurrent Programs, 388 7.2.1 Defining a Path, 388 7.2.2 Path-Based Testing and Coverage Criteria, 391 7.3 Definitions of Correctness and Faults for Concurrent Programs, 395 7.3.1 Defining Correctness for Concurrent Programs, 395 7.3.2 Failures and Faults in Concurrent Programs, 397 7.3.3 Deadlock, Livelock, and Starvation, 400 7.4 Approaches to Testing Concurrent Programs, 408 7.4.1 Nondeterministic Testing, 409 7.4.2 Deterministic Testing, 410 7.4.3 Combinations of Deterministic and Nondeterministic Testing, 414 7.5 Reachability Testing, 419 7.5.1 Reachability Testing Process, 420 7.5.2 SYN-Sequences for Reachability Testing, 424 7.5.3 Race Analysis of SYN-Sequences, 429 7.5.4 Timestamp Assignment, 433 7.5.5 Computing Race Variants, 439 7.5.6 Reachability Testing Algorithm, 441 7.5.7 Research Directions, 447 Further Reading, 449 References, 449 Exercises, 452 Index 457

PREFACE This is a textbook on multithreaded programming. The objective of this book is to teach students about languages and libraries for multithreaded programming, to help students develop problem-solving and programming skills, and to describe and demonstrate various testing and debugging techniques that have been developed for multithreaded programs over the past 20 years. It covers threads, semaphores, locks, monitors, message passing, and the relevant parts of Java, the POSIX Pthreads library, and the Windows Win32 Application Programming Interface (API). The book is unique in that it provides in-depth coverage on testing and debugging multithreaded programs, a topic that typically receives little attention. The title Modern Multithreading reflects the fact that there are effective and relatively new testing and debugging techniques for multithreaded programs. The material in this book was developed in concurrent programming courses that the authors have taught for 20 years. This material includes results from the authors research in concurrent programming, emphasizing tools and techniques that are of practical use. A class library has been implemented to provide working examples of all the material that is covered. Classroom Use In our experience, students have a hard time learning to write concurrent programs. If they manage to get their programs to run, they usually encounter deadlocks and other intermittent failures, and soon discover how difficult it is to reproduce the failures and locate the cause of the problem. Essentially, they have no way to check the correctness of their programs, which interferes with learning. Instructors face the same problem when grading multithreaded programs. It xi

xii PREFACE is tedious, time consuming, and often impossible to assess student programs by hand. The class libraries that we have developed, and the testing techniques they support, can be used to assess student programs. When we assign programming problems in our courses, we also provide test cases that the students must use to assess the correctness of their programs. This is very helpful for the students and the instructors. This book is designed for upper-level undergraduates and graduate students in computer science. It can be used as a main text in a concurrent programming course or could be used as a supplementary text for an operating systems course or a software engineering course. Since the text emphasizes practical material, provides working code, and addresses testing and debugging problems that receive little or no attention in many other books, we believe that it will also be helpful to programmers in industry. The text assumes that students have the following background: ž Programming experience as typically gained in CS 1 and CS 2 courses. ž Knowledge of elementary data structures as learned in a CS 2 course. ž An understanding of Java fundamentals. Students should be familiar with object-oriented programming in Java, but no advanced knowledge is necessary. ž An understanding of C++ fundamentals. We use only the basic objectoriented programming features of C++. ž A prior course on operating systems is helpful but not required. We have made an effort to minimize the differences between our Java and C++ programs. We use object-oriented features that are common to both languages, and the class library has been implemented in both languages. Although we don t illustrate every example in both Java and C++, the differences are very minor and it is easy to translate program examples from one language to the other. Content The book has seven chapters. Chapter 1 defines operating systems terms such as process, thread, andcontext switch. It then shows how to create threads, first in Java and then in C++ using both the POSIX Pthreads library and the Win32 API. A C++ Thread class is provided to hide the details of thread creation in Pthreads/Win32. C++ programs that use the Thread class look remarkably similar to multithreaded Java programs. Fundamental concepts, such as atomicity and nondeterminism, are described using simple program examples. Chapter 1 ends by listing the issues and problems that arise when testing and debugging multithreaded programs. To illustrate the interesting things to come, we present a simple multithreaded C++ program that is capable of tracing and replaying its own executions. Chapter 2 introduces concurrent programming by describing various solutions to the critical section problem. This problem is easy to understand but hard

PREFACE xiii to solve. The advantage of focusing on this problem is that it can be solved without introducing complicated new programming constructs. Students gain a quick appreciation for the programming skills that they need to acquire. Chapter 2 also demonstrates how to trace and replay Peterson s solution to the critical section problem, which offers a straightforward introduction to several testing and debugging issues. The synchronization library implements the various techniques that are described. Chapters 3, 4, and 5 cover semaphores, monitors and message passing, respectively. Each chapter describes one of these constructs and shows how to use it to solve programming problems. Semaphore and Lock classes for Java and C++/Win32/Pthreads are presented in Chapter 3. Chapter 4 presents monitor classes for Java and C++/Win32/Pthreads. Chapter 5 presents mailbox classes with send/receive methods and a selective wait statement. These chapters also cover the built-in support that Win32 and Pthreads provide for these constructs, as well as the support provided by J2SE 5.0 (Java 2 Platform, Standard Edition 5.0). Each chapter addresses a particular testing or debugging problem and shows how to solve it. The synchronization library implements the testing and debugging techniques so that students can apply them to their own programs. Chapter 6 covers message passing in a distributed environment. It presents several Java mailbox classes that hide the details of TCP message passing and shows how to solve several distributed programming problems in Java. It also shows how to test and debug programs in a distributed environment (e.g., accurately tracing program executions by using vector timestamps). This chapter by no means provides complete coverage of distributed programming. Rather, it is meant to introduce students to the difficulty of distributed programming and to show them that the testing and debugging techniques presented in earlier chapters can be extended to work in a distributed environment. The synchronization library implements the various techniques. Chapter 7 covers concepts that are fundamental to testing and debugging concurrent programs. It defines important terms, presents several test coverage criteria for concurrent programs, and describes the various approaches to testing concurrent programs. This chapter organizes and summarizes the testing and debugging material that is presented in depth in Chapters 2 to 6. This organization provides two paths through the text. Instructors can cover the testing and debugging material in the last sections of Chapters 2 to 6 as they go through those chapters, or they can cover those sections when they cover Chapter 7. Chapter 7 also discusses reachability testing, which offers a bridge between testing and verification, and is implemented in the synchronization library. Each chapter has exercises at the end. Some of the exercises explore the concepts covered in the chapter, whereas others require a program to be written. In our courses we cover all the chapters and give six homework assignments, two in-class exams, and a project. We usually supplement the text with readings on model checking, process algebra, specification languages, and other research topics.