DEV Community

Ujjawal Kumar
Ujjawal Kumar

Posted on • Edited on

31 2 2 2 3

Semaphore in Operating System with implementation in C

Semaphore in Operating system
A semaphore is a synchronization construct used in operating systems to control access to shared resources among multiple processes or threads. It is essentially a variable or an abstract data type that provides two fundamental operations: "wait" and "signal" (also known as "P" and "V" operations, respectively).

Here's how semaphores work:

Wait Operation (P): When a process/thread wants to access a shared resource, it first performs a "wait" operation on the semaphore associated with that resource. If the semaphore value is positive (greater than 0), it decrements the value by 1 and continues accessing the resource. If the semaphore value is zero, indicating that the resource is currently being used by another process/thread, the process/thread is blocked or put to sleep until the semaphore becomes available.

Signal Operation (V): When a process/thread finishes using a shared resource, it performs a "signal" operation on the semaphore, which increments the semaphore value by 1. This operation indicates that the resource is now available for other processes/threads waiting on it. If there are any blocked processes/threads waiting for the semaphore, one of them is awakened and granted access to the resource.

Semaphores provide a mechanism to enforce mutual exclusion and prevent race conditions, ensuring that only one process/thread can access a shared resource at a time. They are commonly used in scenarios such as controlling access to critical sections of code, managing concurrent access to shared data structures, and implementing synchronization mechanisms like locks and barriers.

Semaphores can be implemented as either counting semaphores (allowing non-negative integer values) or binary semaphores (with values limited to 0 and 1), depending on the specific synchronization requirements.

Semaphore design

Code:



#include <stdio.h>
#include <pthread.h>

typedef struct {
    pthread_mutex_t mutex;
    pthread_cond_t condition;
    int value;
} semaphore;

void semaphore_init(semaphore* sem, int initial_value) {
    pthread_mutex_init(&(sem->mutex), NULL);
    pthread_cond_init(&(sem->condition), NULL);
    sem->value = initial_value;
}

void semaphore_wait(semaphore* sem) {
    pthread_mutex_lock(&(sem->mutex));
    while (sem->value <= 0) {
        pthread_cond_wait(&(sem->condition), &(sem->mutex));
    }
    sem->value--;
    pthread_mutex_unlock(&(sem->mutex));
}

void semaphore_signal(semaphore* sem) {
    pthread_mutex_lock(&(sem->mutex));
    sem->value++;
    pthread_cond_signal(&(sem->condition));
    pthread_mutex_unlock(&(sem->mutex));
}

void* thread_function(void* arg) {
    semaphore* sem = (semaphore*)arg;

    printf("Thread waiting\n");
    semaphore_wait(sem);

    printf("Thread acquired the semaphore\n");
    // Perform some critical section or shared resource access here

    printf("Thread releasing the semaphore\n");
    semaphore_signal(sem);

    return NULL;
}

int main() {
    semaphore sem;
    semaphore_init(&sem, 1); // Initialize the semaphore with initial value 1

    pthread_t thread;
    pthread_create(&thread, NULL, thread_function, (void*)&sem);

    // Main thread also performs some work
    printf("Main thread performing some work\n");

    // Main thread waits for the semaphore
    printf("Main thread waiting\n");
    semaphore_wait(&sem);

    printf("Main thread acquired the semaphore\n");
    // Perform some critical section or shared resource access here

    printf("Main thread releasing the semaphore\n");
    semaphore_signal(&sem);

    pthread_join(thread, NULL);

    return 0;
}



Enter fullscreen mode Exit fullscreen mode

Output:



Main thread performing some work
Main thread waiting
Main thread acquired the semaphore
Main thread releasing the semaphore
Thread waiting
Thread acquired the semaphore
Thread releasing the semaphore



Enter fullscreen mode Exit fullscreen mode

If you liked this article then please like and share, Thanks for reading 🙏.

Checkout this also: https://www.youtube.com/@endeavourmonk

Image of AssemblyAI

Automatic Speech Recognition with AssemblyAI

Experience near-human accuracy, low-latency performance, and advanced Speech AI capabilities with AssemblyAI's Speech-to-Text API. Sign up today and get $50 in API credit. No credit card required.

Try the API

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay