15
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 - Hörbücher MULTITHREADING Implementing, Testing, and Debugging Multithreaded Java and C++/Pthreads/Win32 Programs RICHARD H. CARVER KUO-CHUNG TAI A JOHN WILEY

  • Upload
    doandan

  • View
    271

  • Download
    5

Embed Size (px)

Citation preview

  • MODERN MULTITHREADING

    Implementing, Testing, andDebugging Multithreaded Java andC++/Pthreads/Win32 Programs

    RICHARD H. CARVERKUO-CHUNG TAI

    A JOHN WILEY & SONS, INC., PUBLICATION

    Innodata0471744166.jpg

  • MODERN MULTITHREADING

  • MODERN MULTITHREADING

    Implementing, Testing, andDebugging Multithreaded Java andC++/Pthreads/Win32 Programs

    RICHARD H. CARVERKUO-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 anyform 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, withouteither the prior written permission of the Publisher, or authorization through payment of theappropriate per-copy fee to the Copyright Clearance Center, Inc., 222 Rosewood Drive, Danvers,

    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 athttp://www.wiley.com/go/permission.

    Limit of Liability/Disclaimer of Warranty: While the publisher and author have used their bestefforts in preparing this book, they make no representations or warranties with respect to theaccuracy or completeness of the contents of this book and specifically disclaim any impliedwarranties of merchantability or fitness for a particular purpose. No warranty may be created orextended by sales representatives or written sales materials. The advice and strategies containedherein may not be suitable for your situation. You should consult with a professional whereappropriate. Neither the publisher nor author shall be liable for any loss of profit or any othercommercial damages, including but not limited to special, incidental, consequential, or otherdamages.

    For general information on our other products and services or for technical support, please contactour Customer Care Department within the United States at (800) 762-2974, outside the UnitedStates 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 printmay not be available in electronic formats. For more information about Wiley products, visit ourweb site at www.wiley.com.

    Library of Congress Cataloging-in-Publication Data:

    Carver, Richard H., 1960Modern 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 2006005.11dc22

    2005045775

    Printed in the United States of America.

    10 9 8 7 6 5 4 3 2 1

    MA 01923, (978) 750-8400, fax (978) 750-4470, or on the web at www.copyright.com. Requests

    http://www.copyright.comhttp://www.wiley.com/go/permissionhttp://www.wiley.com

  • CONTENTS

    Preface xi

    1 Introduction to Concurrent Programming 1

    1.1 Processes and Threads: An Operating Systems View, 11.2 Advantages of Multithreading, 31.3 Threads in Java, 41.4 Threads in Win32, 61.5 Pthreads, 91.6 C++ Thread Class, 14

    1.6.1 C++ Class Thread for Win32, 141.6.2 C++ Class Thread for Pthreads, 19

    1.7 Thread Communication, 191.7.1 Nondeterministic Execution Behavior, 231.7.2 Atomic Actions, 25

    1.8 Testing and Debugging Multithreaded Programs, 291.8.1 Problems and Issues, 301.8.2 Class TDThread for Testing and Debugging, 341.8.3 Tracing and Replaying Executions with Class Template

    sharedVariable, 371.9 Thread Synchronization, 38

    Further Reading, 38References, 39Exercises, 41

    v

  • vi CONTENTS

    2 The Critical Section Problem 46

    2.1 Software Solutions to the Two-Thread Critical SectionProblem, 472.1.1 Incorrect Solution 1, 482.1.2 Incorrect Solution 2, 492.1.3 Incorrect Solution 3, 502.1.4 Petersons Algorithm, 522.1.5 Using the volatile Modifier, 53

    2.2 Ticket-Based Solutions to the n-Thread Critical SectionProblem, 542.2.1 Ticket Algorithm, 542.2.2 Bakery Algorithm, 56

    2.3 Hardware Solutions to the n-Thread Critical SectionProblem, 582.3.1 Partial Solution, 592.3.2 Complete Solution, 592.3.3 Note on Busy-Waiting, 60

    2.4 Deadlock, Livelock, and Starvation, 622.4.1 Deadlock, 622.4.2 Livelock, 622.4.3 Starvation, 63

    2.5 Tracing and Replay for Shared Variables, 642.5.1 ReadWrite-Sequences, 652.5.2 Alternative Definition of ReadWrite-Sequences, 672.5.3 Tracing and Replaying ReadWrite-Sequences, 682.5.4 Class Template sharedVariable, 702.5.5 Putting It All Together, 712.5.6 Note on Shared Memory Consistency, 74

    Further Reading, 77References, 78Exercises, 79

    3 Semaphores and Locks 84

    3.1 Counting Semaphores, 843.2 Using Semaphores, 86

    3.2.1 Resource Allocation, 863.2.2 More Semaphore Patterns, 87

    3.3 Binary Semaphores and Locks, 903.4 Implementing Semaphores, 92

    3.4.1 Implementing P() and V(), 923.4.2 VP() Operation, 94

    3.5 Semaphore-Based Solutions to Concurrent ProgrammingProblems, 963.5.1 Event Ordering, 96

  • CONTENTS vii

    3.5.2 Bounded Buffer, 963.5.3 Dining Philosophers, 983.5.4 Readers and Writers, 1013.5.5 Simulating Counting Semaphores, 108

    3.6 Semaphores and Locks in Java, 1113.6.1 Class countingSemaphore, 1113.6.2 Class mutexLock, 1133.6.3 Class Semaphore, 1153.6.4 Class ReentrantLock, 1163.6.5 Example: Java Bounded Buffer, 116

    3.7 Semaphores and Locks in Win32, 1193.7.1 CRITICAL SECTION, 1193.7.2 Mutex, 1223.7.3 Semaphore, 1243.7.4 Events, 1323.7.5 Other Synchronization Functions, 1343.7.6 Example: C++/Win32 Bounded Buffer, 134

    3.8 Semaphores and Locks in Pthreads, 1343.8.1 Mutex, 1363.8.2 Semaphore, 137

    3.9 Another Note on Shared Memory Consistency, 1413.10 Tracing, Testing, and Replay for Semaphores and Locks, 143

    3.10.1 Nondeterministic Testing with the LocksetAlgorithm, 143

    3.10.2 Simple SYN-Sequences for Semaphores andLocks, 146

    3.10.3 Tracing and Replaying Simple PV-Sequences andLockUnlock-Sequences, 150

    3.10.4 Deadlock Detection, 1543.10.5 Reachability Testing for Semaphores and Locks, 1573.10.6 Putting It All Together, 160

    Further Reading, 163References, 164Exercises, 166

    4 Monitors 177

    4.1 Definition of Monitors, 1784.1.1 Mutual Exclusion, 1784.1.2 Condition Variables and SC Signaling, 178

    4.2 Monitor-Based Solutions to Concurrent ProgrammingProblems, 1824.2.1 Simulating Counting Semaphores, 1824.2.2 Simulating Binary Semaphores, 1834.2.3 Dining Philosophers, 1834.2.4 Readers and Writers, 187

  • viii CONTENTS

    4.3 Monitors in Java, 1874.3.1 Better countingSemaphore, 1904.3.2 notify vs. notifyAll, 1914.3.3 Simulating Multiple Condition Variables, 194

    4.4 Monitors in Pthreads, 1944.4.1 Pthreads Condition Variables, 1964.4.2 Condition Variables in J2SE 5.0, 196

    4.5 Signaling Disciplines, 1994.5.1 Signal-and-Urgent-Wait, 1994.5.2 Signal-and-Exit, 2024.5.3 Urgent-Signal-and-Continue, 2044.5.4 Comparing SU and SC Signals, 204

    4.6 Using Semaphores to Implement Monitors, 2064.6.1 SC Signaling, 2064.6.2 SU Signaling, 207

    4.7 Monitor Toolbox for Java, 2094.7.1 Toolbox for SC Signaling in Java, 2104.7.2 Toolbox for SU Signaling in Java, 210

    4.8 Monitor Toolbox for Win32/C++/Pthreads, 2114.8.1 Toolbox for SC Signaling in C++/Win32/Pthreads, 2134.8.2 Toolbox for SU Signaling in C++/Win32/Pthreads, 213

    4.9 Nested Monitor Calls, 2134.10 Tracing and Replay for Monitors, 217

    4.10.1 Simple M-Sequences, 2174.10.2 Tracing and Replaying Simple M-Sequences, 2194.10.3 Other Approaches to Program Replay, 220

    4.11 Testing Monitor-Based Programs, 2224.11.1 M-Sequences, 2224.11.2 Determining the Feasibility of an M-Sequence, 2274.11.3 Determining the Feasibility of a

    Communication-Sequence, 2334.11.4 Reachability Testing for Monitors, 2334.11.5 Putting It All Together, 235

    Further Reading, 243References, 243Exercises, 245

    5 Message Passing 258

    5.1 Channel Objects, 2585.1.1 Channel Objects in Java, 2595.1.2 Channel Objects in C++/Win32, 263

    5.2 Rendezvous, 2665.3 Selective Wait, 272

  • CONTENTS ix

    5.4 Message-Based Solutions to Concurrent ProgrammingProblems, 2755.4.1 Readers and Writers, 2755.4.2 Resource Allocation, 2785.4.3 Simulating Counting Semaphores, 281

    5.5 Tracing, Testing, and Replay for Message-PassingPrograms, 2815.5.1 SR-Sequences, 2825.5.2 Simple SR-Sequences, 2885.5.3 Determining the Feasibility of an SR-Sequence, 2905.5.4 Deterministic Testing, 2965.5.5 Reachability Testing for Message-Passing

    Programs, 2975.5.6 Putting It All Together, 299

    Further Reading, 304References, 304Exercises, 304

    6 Message Passing in Distributed Programs 312

    6.1 TCP Sockets, 3126.1.1 Channel Reliability, 3136.1.2 TCP Sockets in Java, 314

    6.2 Java TCP Channel Classes, 3176.2.1 Classes TCPSender and TCPMailbox, 3186.2.2 Classes TCPSynchronousSender and

    TCPSynchronousMailbox, 3266.2.3 Class TCPSelectableSynchronousMailbox, 328

    6.3 Timestamps and Event Ordering, 3296.3.1 Event-Ordering Problems, 3306.3.2 Local Real-Time Clocks, 3316.3.3 Global Real-Time Clocks, 3326.3.4 Causality, 3326.3.5 Integer Timestamps, 3346.3.6 Vector Timestamps, 3356.3.7 Timestamps for Programs Using Messages and Shared

    Variables, 3396.4 Message-Based Solutions to Distributed Programming

    Problems, 3416.4.1 Distributed Mutual Exclusion, 3416.4.2 Distributed Readers and Writers, 3466.4.3 Alternating Bit Protocol, 348

    6.5 Testing and Debugging Distributed Programs, 3536.5.1 Object-Based Sequences, 3536.5.2 Simple Sequences, 362

  • x CONTENTS

    6.5.3 Tracing, Testing, and Replaying CARC-Sequences andCSC-Sequences, 362

    6.5.4 Putting It All Together, 3696.5.5 Other Approaches to Replaying Distributed

    Programs, 371Further Reading, 374References, 375Exercises, 376

    7 Testing and Debugging Concurrent Programs 381

    7.1 Synchronization Sequences of Concurrent Programs, 3837.1.1 Complete Events vs. Simple Events, 3837.1.2 Total Ordering vs. Partial Ordering, 386

    7.2 Paths of Concurrent Programs, 3887.2.1 Defining a Path, 3887.2.2 Path-Based Testing and Coverage Criteria, 391

    7.3 Definitions of Correctness and Faults for ConcurrentPrograms, 3957.3.1 Defining Correctness for Concurrent Programs, 3957.3.2 Failures and Faults in Concurrent Programs, 3977.3.3 Deadlock, Livelock, and Starvation, 400

    7.4 Approaches to Testing Concurrent Programs, 4087.4.1 Nondeterministic Testing, 4097.4.2 Deterministic Testing, 4107.4.3 Combinations of Deterministic and Nondeterministic

    Testing, 4147.5 Reachability Testing, 419

    7.5.1 Reachability Testing Process, 4207.5.2 SYN-Sequences for Reachability Testing, 4247.5.3 Race Analysis of SYN-Sequences, 4297.5.4 Timestamp Assignment, 4337.5.5 Computing Race Variants, 4397.5.6 Reachability Testing Algorithm, 4417.5.7 Research Directions, 447

    Further Reading, 449References, 449Exercises, 452

    Index 457

  • PREFACE

    This is a textbook on multithreaded programming. The objective of this bookis to teach students about languages and libraries for multithreaded program-ming, to help students develop problem-solving and programming skills, and todescribe and demonstrate various testing and debugging techniques that have beendeveloped 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 ProgrammingInterface (API).

    The book is unique in that it provides in-depth coverage on testing and debug-ging multithreaded programs, a topic that typically receives little attention. Thetitle Modern Multithreading reflects the fact that there are effective and relativelynew testing and debugging techniques for multithreaded programs. The materialin this book was developed in concurrent programming courses that the authorshave taught for 20 years. This material includes results from the authors researchin concurrent programming, emphasizing tools and techniques that are of practi-cal use. A class library has been implemented to provide working examples ofall the material that is covered.

    Classroom Use

    In our experience, students have a hard time learning to write concurrent pro-grams. If they manage to get their programs to run, they usually encounterdeadlocks and other intermittent failures, and soon discover how difficult it is toreproduce the failures and locate the cause of the problem. Essentially, they haveno way to check the correctness of their programs, which interferes with learn-ing. Instructors face the same problem when grading multithreaded programs. It

    xi

  • xii PREFACE

    is tedious, time consuming, and often impossible to assess student programs byhand. The class libraries that we have developed, and the testing techniques theysupport, can be used to assess student programs. When we assign programmingproblems in our courses, we also provide test cases that the students must useto assess the correctness of their programs. This is very helpful for the studentsand the instructors.

    This book is designed for upper-level undergraduates and graduate studentsin computer science. It can be used as a main text in a concurrent programmingcourse or could be used as a supplementary text for an operating systems course ora software engineering course. Since the text emphasizes practical material, pro-vides working code, and addresses testing and debugging problems that receivelittle or no attention in many other books, we believe that it will also be helpfulto 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 isnecessary.

    An understanding of C++ fundamentals. We use only the basic object-oriented 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 dontillustrate every example in both Java and C++, the differences are very minorand 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 suchas process, thread, and context switch. It then shows how to create threads, firstin Java and then in C++ using both the POSIX Pthreads library and the Win32API. A C++ Thread class is provided to hide the details of thread creationin Pthreads/Win32. C++ programs that use the Thread class look remarkablysimilar to multithreaded Java programs. Fundamental concepts, such as atomicityand nondeterminism, are described using simple program examples. Chapter 1ends by listing the issues and problems that arise when testing and debuggingmultithreaded programs. To illustrate the interesting things to come, we presenta simple multithreaded C++ program that is capable of tracing and replaying itsown executions.

    Chapter 2 introduces concurrent programming by describing various solutionsto 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 solvedwithout introducing complicated new programming constructs. Students gain aquick appreciation for the programming skills that they need to acquire. Chapter 2also demonstrates how to trace and replay Petersons solution to the criticalsection problem, which offers a straightforward introduction to several testing anddebugging issues. The synchronization library implements the various techniquesthat are described.

    Chapters 3, 4, and 5 cover semaphores, monitors and message passing, respec-tively. Each chapter describes one of these constructs and shows how to useit to solve programming problems. Semaphore and Lock classes for Java andC++/Win32/Pthreads are presented in Chapter 3. Chapter 4 presents monitorclasses for Java and C++/Win32/Pthreads. Chapter 5 presents mailbox classeswith send/receive methods and a selective wait statement. These chapters alsocover 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 Edi-tion 5.0). Each chapter addresses a particular testing or debugging problemand shows how to solve it. The synchronization library implements the test-ing and debugging techniques so that students can apply them to their ownprograms.

    Chapter 6 covers message passing in a distributed environment. It presentsseveral Java mailbox classes that hide the details of TCP message passing andshows how to solve several distributed programming problems in Java. It alsoshows how to test and debug programs in a distributed environment (e.g., accu-rately tracing program executions by using vector timestamps). This chapter byno means provides complete coverage of distributed programming. Rather, it ismeant to introduce students to the difficulty of distributed programming and toshow them that the testing and debugging techniques presented in earlier chapterscan be extended to work in a distributed environment. The synchronization libraryimplements the various techniques.

    Chapter 7 covers concepts that are fundamental to testing and debuggingconcurrent programs. It defines important terms, presents several test coveragecriteria for concurrent programs, and describes the various approaches to test-ing concurrent programs. This chapter organizes and summarizes the testing anddebugging material that is presented in depth in Chapters 2 to 6. This organiza-tion provides two paths through the text. Instructors can cover the testing anddebugging material in the last sections of Chapters 2 to 6 as they go through thosechapters, or they can cover those sections when they cover Chapter 7. Chapter7 also discusses reachability testing, which offers a bridge between testing andverification, and is implemented in the synchronization library.

    Each chapter has exercises at the end. Some of the exercises explore the con-cepts 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 readingson model checking, process algebra, specification languages, and other researchtopics.