# Semaphores are Surprisingly Versatile

DevFeed: [Semaphores are Surprisingly Versatile](<https://devfeed.tech/articles/semaphores-are-surprisingly-versatile-21001.md>)

Original publisher: [Read original article](<https://preshing.com/20150316/semaphores-are-surprisingly-versatile>)

Author: Jeff Preshing

Published: 2015-03-16T09:50:00Z

Content type: tutorial

Language: en

Sources: [Jeff Preshing](<https://devfeed.tech/sources/jeff-preshing.md>)

Topics: [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>), [Programming](<https://devfeed.tech/topics/programming.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Code](<https://devfeed.tech/topics/code.md>), [Kernel](<https://devfeed.tech/topics/kernel.md>), [Library](<https://devfeed.tech/topics/library.md>), [Linux](<https://devfeed.tech/topics/linux.md>), [macOS](<https://devfeed.tech/topics/macos.md>), [iOS](<https://devfeed.tech/topics/ios.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [cpu](<https://devfeed.tech/tags/cpu.md>), [github](<https://devfeed.tech/tags/github.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [kernel](<https://devfeed.tech/tags/kernel.md>), [library](<https://devfeed.tech/tags/library.md>), [portable](<https://devfeed.tech/tags/portable.md>), [posix](<https://devfeed.tech/tags/posix.md>), [programming](<https://devfeed.tech/tags/programming.md>), [queue](<https://devfeed.tech/tags/queue.md>), [source](<https://devfeed.tech/tags/source.md>), [thread](<https://devfeed.tech/tags/thread.md>)

## AI overview

This article explains how semaphores make threads wait efficiently and demonstrates that semaphores combined with atomic operations can implement lightweight mutexes, auto-reset events, read-write locks, and other synchronization primitives. It also describes userspace spinning, kernel sleeping, and portable C++11 implementations for multiple operating systems.

## Source excerpt

In multithreaded programming, it's important to make threads wait. They must wait for exclusive access to a resource. They must wait when there's no work available. One way to make threads wait - and put them to sleep inside the kernel, so that they no longer take any CPU time - is with a semaphore. I used to think semaphores were strange and old-fashioned. They were invented by Edsger Dijkstra back in the early 1960s, before anyone had done much multithreaded programming, or much programming at all, for that matter. I knew that a semaphore could keep track of available units of a resource, or function as a clunky kind of mutex, but that seemed to be about it. My opinion changed once I realized that, using only semaphores and atomic operations, it's possible to implement all of the following primitives: A Lightweight Mutex A Lightweight Auto-Reset Event Object A Lightweight Read-Write Lock Another Solution to the Dining Philosophers Problem A Lightweight Semaphore With Partial Spinning Not only that, but these implementations share some desirable properties. They're lightweight, in the sense that some operations happen entirely in userspace, and they can (optionally) spin for a short period before sleeping in the kernel. You'll find all of the C++11 source code on GitHub. Since the standard C++11 library does not include semaphores, I've also provided a portable Semaphore class that maps directly to native semaphores on Windows, MacOS, iOS, Linux and other POSIX environments. You should be able to drop any of these primitives into almost any existing C++11 project. A Semaphore Is Like a Bouncer Imagine a set of waiting threads, lined up in a queue - much like a lineup in front of a busy nightclub or theatre. A semaphore is like a bouncer at the front of the lineup. He only allows threads to proceed when instructed to do so. Each thread decides for itself when to join the queue. Dijkstra called this the P operation. P originally stood for some funny-sounding Dutch wo