As computers grow more complex, users demand they be able to run more than one operation at the same time. For example, one might want to play a song through a Bluetooth connection while simultaneously listening to the GPS for where to turn next. This is multitasking. Now, if a system is running more than one app at the same time, what happens when two applications request the same resource? Simply, the system has a dedicated variable that keeps track of which resources are available, and each app has to get permission from that variable first. Once one app is done using that resource, the variable changes, allowing another app to use it. That variable is called a semaphore in OS.

Semaphores have been around in the computing world for over 50 years. In fact, semaphores first appeared back in 1965, when a new technique for managing processes began taking advantage of this single-integer variable to sync up the progress of any interacting processing. It holds a non-negative integer value used by all threads. It typically comes with a signal and a wait operation. For someone who is looking to get into computer coding and wants to work behind the scenes of an operating system and its programming, it is necessary to understand semaphore in OS (operating system). Once you understand the basics of what these different signals can do, you'll then be able to build on top of the signals and use each in constructing more complex applications.

Types of Semaphore in OS

The two most classic forms of semaphore in OS are signal and wait. A signal gives increments and the value of the argument. It sends a straight signal (instead of waiting). The symbol itself may vary based on the operating system. The other is a wait. This decrements the value of a used argument. Due to this, the argument becomes a non-negative (or anything that is greater than the value of 1).


​Basic Functions and Properties of Semaphores

Semaphores in OS are straightforward and simple. As each is broken down into either wait or signal, it is possible to control several processes, including far more complex programs. Most programs work on the signal and wait programming, with different bits of coding firing off when instructed to, or waiting until it receives the activation signal. It's also able to work with a non-negative integer. By combining different semaphores, it's possible to build up several critical sections, each of which may interact with the other while using the wait and signal definitions of the semaphore in OS. Plus, by giving each critical section unique access semaphores, it becomes possible to continually build on top of the previous semaphore, making it more complex with every addition. By programming these interactions, you can perform several processes to stem from a singular semaphore.

For example, several processes may hinge on a single semaphore offering the go-ahead signal. Once wait switches to signal, the attached processes the function. It's possible to think of this like turning on a car. The car remains in the off, or wait mode. When the signal is given, power is sent to the car. The stereo turns on, the lights turn on, the engine roars to life, and several other processes begin. All of this takes place when switching from wait to signal. This then holds true when several processes are attached to a single semaphore.

Types of Semaphores

There are two basic semaphores. They are binary and counting.

Binary is one of the most known forms of semaphores. It uses 1's and 0's to send the commands of wait and signal. Much of computer programming is built on binary with programming hinging on the commands for what to do next.

The second option is counting semaphores. With these semaphores, bounded concurrency is used to build up the semaphore in OS.

When Each Type of Semaphore In OS Is Used

While there are two basic forms of semaphores, each is used in a different method. This way, when learning how to take advantage of a semaphore in OS, it is possible to know when to use each.

Counting semaphores are often used when multiple devices are connected to an individual station. For example, if you have three printers connected to a computer, this represents a counting semaphore; while a binary semaphore represents whether a resource is available, this one represents how many printers are available. You have individual units built on top of the base platform, as there are multiple units you're counting on top of the semaphore. Naturally, this is not limited to just printers, though. It can include memory buffers, several hard drives or really anything when a program must reach out and interact with several devices. Sometimes the program itself might work in binary, but when communicating with external devices the signals are signed using a counting semaphore format.

Binary Semaphore

Math formulas on a green board

​Image via Pixabay

The second option is binary semaphore in OS. This is used to give specific access to an individual resource. For example, when a single device is plugged into your computer through a USB port, this is an individual connection requesting individual, exclusive access through the port. The program, operating system or other connecting command center must then give it a wait or a signal command. Because it doesn't need to thread out to multiple devices, these commands perform well on the single device. There are many examples of a single device connecting and requesting exclusive access. In the first example of counting semaphores, there were multiple printers connected to a computer, in which case specific commands to the individual printers had to be sent out. In this example, a single printer can be connected to the computer through a USB port and a binary semaphore will send out the wait or signal command. An individually connected hard drive or any other device that connects with the operating system and interacts with the programming will fall under this binary semaphore.

Mutex Semaphore

Sometimes there is a third semaphore. This third semaphore is rarely used and often not counted as one of the main forms of semaphore in OS. This is known as a mutex semaphore. This is designed for offering mutual exclusive access to an individual resource. By doing this, it allows multiple implementations of the semaphore to connect with the varying devices. Let's continue using the printer reference. Instead of sending a singular signal to an individual printer, or blocking out other undesired printers to ensure the signal reaches the one command printer, a mutex semaphore signal is sent out to all the printers. Here, all the printers will produce the incoming command. This is similar to using the case when connecting devices to a computer and the commands are going outward, from the computer to the connected hardware. If multiple flash drives are connected to an individual USB port (through a USB hub), all three will not send in information to the computer (at least the exact same information). However, with a mutex semaphore, it's possible to send out the same bit of data in a singular mutex command to all connected flash drives in the USB hub.


Photo of a math solutions on a blackboard

​Image via Unsplash

While there are major advantages to using a semaphore in OS, there are also some obvious limitations to using two basic commands to control often complex programs and operating systems. First, there is a priority inversion. 

Giving individual semaphores priority over others is not possible unless the different commands are built into it. If several commands are associated with a single semaphore and are waiting for it to switch to signal instead of command, all the new commands will execute once switched from wait to signal.

However, there might be times where one action goes off before others. In order for this to happen, additional semaphores must be added in to implement new wait commands. This adds extra programming that could be avoided if priority inversion were available.

Not Enforced

The next major drawback to semaphores is that the use of semaphores is not enforced. Everything is used by convention only and builds on top of previous semaphores. This means the construction of one designer may substantially differ from that of others. If a new programmer is brought in to work on the current semaphores, they might have a terrible time trying to worm through the existing semaphores to make any changes or corrections without corrupting the entire program. This connects to the next top limitation to the use of semaphores. If the semaphores are not correctly used, an entire process may be blocked or called deadlock. This is where the process does not receive the signal. In these instances, it is often necessary to deconstruct the entire coding process back to the deadlock to determine the problem and identify the adequate solution.


For anyone who is interested in the background of an operating system, it is critical to understand semaphore in OS. Semaphores are simple in nature. A semaphore uses two individual commands of wait and signal. These simple commands can then be used to build on top of previous commands. As long as correctly used, it is possible to build a complex program off of these individual semaphores. However, because semaphores in OS are not regulated, it can cause issues when bringing in other designers who may not be familiar with how the previous designer built the program (or operating system). However, by fully understanding how semaphores work and what is required to go into the building of such a program correctly, it is possible to take advantage of these semaphores, which have been around for over a half-century.