Table of Contents
Foreword xix
Preface xxiii
Acknowledgments xxvii
About the Author xxix
Part I: Concepts 1
Chapter 1: Introduction 3
Why Concurrency? 3
Program Architecture and Concurrency 6
Layers of Parallelism 8
Why Not Concurrency? 10
Where Are We? 11
Chapter 2: Synchronization and Time 13
Managing Program State 14
Synchronization: Kinds and Techniques 38
Where Are We? 73
Part II: Mechanisms 77
Chapter 3: Threads 79
Threading from 10,001 Feet 80
The Life and Death of Threads 89
Where Are We? 124
Chapter 4: Advanced Threads 127
Thread State 127
Inside Thread Creation and Termination 152
Thread Scheduling 154
Where Are We? 180
Chapter 5: Windows Kernel Synchronization 183
The Basics: Signaling and Waiting 184
Using the Kernel Objects 211
Where Are We? 251
Chapter 6: Data and Control Synchronization 253
Mutual Exclusion 255
Reader/Writer Locks (RWLs) 287
Condition Variables 304
Where Are We? 312
Chapter 7: Thread Pools 315
Thread Pools 101 316
Windows Thread Pools 323
CLR Thread Pool 364
Performance When Using the Thread Pools 391
Where Are We? 398
Chapter 8: Asynchronous Programming Models 399
Asynchronous Programming Model (APM) 400
Event-Based Asynchronous Pattern 421
Where Are We? 427
Chapter 9: Fibers 429
An Overview of Fibers 430
Using Fibers 435
Additional Fiber-Related Topics 445
Building a User-Mode Scheduler 453
Where Are We? 473
Part III: Techniques 475
Chapter 10: Memory Models and Lock Freedom 477
Memory Load and Store Reordering 478
Hardware Atomicity 486
MemoryConsistency Models 506
Examples of Low-Lock Code 520
Where Are We? 541
Chapter 11: Concurrency Hazards 545
Correctness Hazards 546
Liveness Hazards 572
Where Are We? 609
Chapter 12: Parallel Containers 613
Fine-Grained Locking 616
Lock Free 632
Coordination Containers 640
Where Are We? 654
Chapter 13: Data and Task Parallelism 657
Data Parallelism 659
Task Parallelism 684
Message-Based Parallelism 719
Cross-Cutting Concerns 720
Where Are We? 732
Chapter 14: Performance and Scalability 735
Parallel Hardware Architecture 736
Speedup: Parallel vs. Sequential Code 756
Spin Waiting 767
Where Are We? 781
Part IV: Systems 783
Chapter 15: Input and Output 785
Overlapped I/O 786
I/O Cancellation 822
Where Are We? 826
Chapter 16: Graphical User Interfaces 829
GUI Threading Models 830
.NET Asynchronous GUI Features 837
Where Are We? 860
Part V: Appendices 863
Appendix A: Designing Reusable Libraries for Concurrent .NET Programs 865
The 20,000-Foot View 866
The Details 867
Appendix B: Parallel Extensions to .NET 887
Task Parallel Library 888
Parallel LINQ 910
Synchronization Primitives 915
Concurrent Collections 924
Index 931
Forewords & Introductions
I began writing this book towards the end of 2005. At the time, dual-core processors were becoming standard on the mainstream PC's that ordinary (non-programmer) consumers were buying, and a small number of people in industry had begun to make noise about the impending concurrency problem. (Herb Sutter's The Free Lunch is Over paper immediately comes to mind.) The problem people were worried about, of course, was that the software of the past was not written in a way that would allow it to naturally exploit that additional compute power. Contrast that with the never-ending increase in clock speeds. No more free lunch indeed.
It seemed to me that concurrency was going to be an important part of every software developer's job somewhere down the road and that a book like this would be important and useful. Just over two years later, the impact is beginning to ripple up from the operating system, through the libraries, and on up to applications themselves.
This was about the same time I had wrapped up prototyping a small side-project on which I had been burning the midnight oil for the previous six months: Parallel Language Integrated Query (PLINQ). The PLINQ project was a conduit for me to explore the intricacies of concurrency, multi-core, and specifically how parallelism might be used in real-world, everyday programs. I used it as a tool to figure out where the platform was lacking. This was in addition to spending my day job at Microsoft focused on software transactional memory (STM), a technology that in the intervening two years has become somewhat of an industry buzzword. Needless to say, I had become pretty entrenched in all topics concurrency. What better way to get entrenched even further than to write a book on the subject?
As I worked on all of these projects, and eventually PLINQ grew into Parallel Extensions to the .NET Framework, I was amazed at how few good books on Windows concurrency were available. I remember time and time again being astonished or amazed at some intricate and esoteric bit of concurrency-related information, jotting it down, and earmarking it for inclusion in this book. I only wished somebody had written it down before me, so that I didn't need to scour it from numerous sources: hallway conversations, long nights of pouring over Windows and CLR source code, and reading and rereading countless Microsoft employee blogs. But the best books on the topic dated back to the early '90s and, while still really good, focused too much on the mechanics and not on how to structure parallel programs, implement parallel algorithms, deal with concurrency hazards, and other important concepts. Everything else targeted academics and researchers, and not application, system, and library developers.
I set out to write a book that I'd have found fascinating and a useful way to shortcut all of the random bits of information I had to learn throughout. Although it took me a surprisingly long two-and-a-half years to finish this book (!), the state of the art has evolved slowly, and the state of good books on the topic hasn't changed much either. The result of my efforts, I hope, is a new book that is down-to-earth and useful, but still full of very deep technical information. It is for any Windows or .NET developer who believes that concurrency is going to be a fundamental requirement of all software somewhere down the road, as all industry trends seem to imply.
I look forward to kicking back and enjoying this book. And I sincerely hope you do too.
Book Structure
I've structured the book into four major parts. The first, Concepts, introduces concurrency at a high level without going too deep into any one topic. The next part, Mechanisms, focuses squarely on the fundamental platform features, inner workings, and API details. After that, the part on Techniques describes common patterns, best practices, algorithms, and data structures that emerge while writing concurrent software. The fourth part, Systems, covers many of the systemwide architectural and process concerns that frequently arise. There is a progression here. Concepts is first because it develops a basic understanding of concurrency in general. Understanding the content in Techniques would be difficult without a solid understanding of the Mechanisms, and similarly, building real Systems would be impossible without understanding the rest. There is also a collection of Appendices at the end.
Code Requirements
To run code found in this book, you'll need to download some free pieces of software:
- Microsoft Windows SDK. This includes the Microsoft C++ compiler and relevant platform headers and libraries. The latest versions as of this writing are the Windows Vista and Server 2008 SDKs.
- Microsoft .NET Framework SDK. This includes the Microsoft C# and Visual Basic compilers, and relevant framework libraries. The latest version as of this writing is the .NET Framework 3.5 SDK.
Both can be found on MSDN: http://msdn.microsoft.com/.
In addition, it's highly recommended that you consider using Visual Studio. This is not required--and in fact, much of the code in this book was written in emacs--but provides for a more seamless development and debugging experience. Visual Studio 2008 Express Edition can be downloaded for free, although it lacks many useful capabilities such as performance profiling.
Lastly, the Debugging Tools for Windows package--which includes the popular WINDBG debugging utility--might also come in handy, particularly if you don't have Visual Studio. It is freely downloadable from http://www.microsoft.com/. Similarly, the Sysinternals utilities available from http://technet.microsoft.com/sysinternals/ are quite useful for inspecting aspects of the Windows OS.
A companion website for the book will be available simultaneous with publication of the book.
Joe Duffy June 2008
joe@bluebytesoftware.com
Read an Excerpt
I began writing this book towards the end of 2005. At the time, dual-core processors were becoming standard on the mainstream PC's that ordinary (non-programmer) consumers were buying, and a small number of people in industry had begun to make noise about the impending concurrency problem. (Herb Sutter's The Free Lunch is Over paper immediately comes to mind.) The problem people were worried about, of course, was that the software of the past was not written in a way that would allow it to naturally exploit that additional compute power. Contrast that with the never-ending increase in clock speeds. No more free lunch indeed.
It seemed to me that concurrency was going to be an important part of every software developer's job somewhere down the road and that a book like this would be important and useful. Just over two years later, the impact is beginning to ripple up from the operating system, through the libraries, and on up to applications themselves.
This was about the same time I had wrapped up prototyping a small side-project on which I had been burning the midnight oil for the previous six months: Parallel Language Integrated Query (PLINQ). The PLINQ project was a conduit for me to explore the intricacies of concurrency, multi-core, and specifically how parallelism might be used in real-world, everyday programs. I used it as a tool to figure out where the platform was lacking. This was in addition to spending my day job at Microsoft focused on software transactional memory (STM), a technology that in the intervening two years has become somewhat of an industry buzzword. Needless to say, I had become pretty entrenched in all topicsconcurrency. What better way to get entrenched even further than to write a book on the subject?
As I worked on all of these projects, and eventually PLINQ grew into Parallel Extensions to the .NET Framework, I was amazed at how few good books on Windows concurrency were available. I remember time and time again being astonished or amazed at some intricate and esoteric bit of concurrency-related information, jotting it down, and earmarking it for inclusion in this book. I only wished somebody had written it down before me, so that I didn't need to scour it from numerous sources: hallway conversations, long nights of pouring over Windows and CLR source code, and reading and rereading countless Microsoft employee blogs. But the best books on the topic dated back to the early '90s and, while still really good, focused too much on the mechanics and not on how to structure parallel programs, implement parallel algorithms, deal with concurrency hazards, and other important concepts. Everything else targeted academics and researchers, and not application, system, and library developers.
I set out to write a book that I'd have found fascinating and a useful way to shortcut all of the random bits of information I had to learn throughout. Although it took me a surprisingly long two-and-a-half years to finish this book (!), the state of the art has evolved slowly, and the state of good books on the topic hasn't changed much either. The result of my efforts, I hope, is a new book that is down-to-earth and useful, but still full of very deep technical information. It is for any Windows or .NET developer who believes that concurrency is going to be a fundamental requirement of all software somewhere down the road, as all industry trends seem to imply.
I look forward to kicking back and enjoying this book. And I sincerely hope you do too.Book Structure
I've structured the book into four major parts. The first, Concepts, introduces concurrency at a high level without going too deep into any one topic. The next part, Mechanisms, focuses squarely on the fundamental platform features, inner workings, and API details. After that, the part on Techniques describes common patterns, best practices, algorithms, and data structures that emerge while writing concurrent software. The fourth part, Systems, covers many of the systemwide architectural and process concerns that frequently arise. There is a progression here. Concepts is first because it develops a basic understanding of concurrency in general. Understanding the content in Techniques would be difficult without a solid understanding of the Mechanisms, and similarly, building real Systems would be impossible without understanding the rest. There is also a collection of Appendices at the end.Code Requirements
To run code found in this book, you'll need to download some free pieces of software:
- Microsoft Windows SDK. This includes the Microsoft C++ compiler and relevant platform headers and libraries. The latest versions as of this writing are the Windows Vista and Server 2008 SDKs.
- Microsoft .NET Framework SDK. This includes the Microsoft C# and Visual Basic compilers, and relevant framework libraries. The latest version as of this writing is the .NET Framework 3.5 SDK.
Both can be found on MSDN: http://msdn.microsoft.com/.
In addition, it's highly recommended that you consider using Visual Studio. This is not requiredand in fact, much of the code in this book was written in emacsbut provides for a more seamless development and debugging experience. Visual Studio 2008 Express Edition can be downloaded for free, although it lacks many useful capabilities such as performance profiling.
Lastly, the Debugging Tools for Windows packagewhich includes the popular WINDBG debugging utilitymight also come in handy, particularly if you don't have Visual Studio. It is freely downloadable from http://www.microsoft.com/. Similarly, the Sysinternals utilities available from http://technet.microsoft.com/sysinternals/ are quite useful for inspecting aspects of the Windows OS.
A companion website for the book will be available simultaneous with publication of the book.
Joe Duffy
June 2008
joe@bluebytesoftware.com