Synchronization is used to coordinate the activity of multiple threads. There are various situations where it is necessary; this might be to ensure that shared resources are not accessed by multiple threads simultaneously or that all work on those resources is com-plete before new work starts.
Most operating systems provide a rich set of synchronization primitives. It is usually most appropriate to use these rather than attempting to write custom methods of syn-chronization. There are two reasons for this. Synchronization primitives provided by the operating system will usually be recognized by the tools provided with that operating system. Hence, the tools will be able to do a better job of detecting data races or cor-rectly labeling synchronization costs. The operating system will often provide support for sharing the primitives between threads or processes, which can be hard to do efficiently without operating system support. However, the most critical consideration is that the code provided by the operating system is unlikely to contain bugs. Discussion of writing custom synchronization primitives is covered in Chapter 8, “Hand-Coded Synchronization and Sharing.”