Semaphore in C

Reading time: 15 minutes

Semaphore is a data handling technique which is very useful in process synchronization and multithreading. In this article, we will explore how we can use semaphore in C language.

We have the POSIX semaphore library in Linux systems. We will use this in our case.

The basic code of a semaphore cannot be typed directly into client code as it should be atomic and writing code directly would lead to a context switch which would lead to unexpected results.

The POSIX system in Linux presents its own built-in semaphore library. To use it, we have to :

  • Include semaphore.h header file
  • Compile the code by linking with -lpthread -lrt

To lock a semaphore, we can use the sem_wait function:


int sem_wait(sem_t *sem);

To release or signal a semaphore, we use the sem_post function:


int sem_post(sem_t *sem);

A semaphore is initialised by using sem_init (for processes or threads) or sem_open (for Interprocess communication).


sem_init(sem_t *sem, int pshared, unsigned int value);

sem : Specifies the semaphore to be initialized.
pshared : This argument specifies whether or not the newly initialized semaphore is shared between processes or between threads. A non-zero value means the semaphore is shared between processes and a value of zero means it is shared between threads.
value : Specifies the value to assign to the newly initialized semaphore.

To destroy a semaphore, we can use sem_destroy.


sem_destoy(sem_t *mutex);

To declare a semaphore, the data type is sem_t.


#include < stdio.h> 
#include < pthread.h> 
#include < semaphore.h> 
#include < unistd.h> 
sem_t mutex; 
void* thread(void* arg) 
{ 
    //wait 
    sem_wait(&mutex); 
    printf("\nEntered thread\n"); 
  
    //critical section 
    sleep(4); 
      
    //signal 
    printf("\n Exit thread\n"); 
    sem_post(&mutex); 
} 
int main() 
{ 
    sem_init(&mutex, 0, 1); 
    pthread_t t1,t2; 
    pthread_create(&t1,NULL,thread,NULL); 
    sleep(2); 
    pthread_create(&t2,NULL,thread,NULL); 
    pthread_join(t1,NULL); 
    pthread_join(t2,NULL); 
    sem_destroy(&mutex); 
    return 0; 
} 

Compilation should be done with gcc a.c -lpthread -lrt

Explanation of above code

2 threads are being created, one 2 seconds after the first one.
The first thread will sleep for 4 seconds after acquiring the lock.
Thus the second thread will not enter immediately after it is called, it will enter 4 – 2 = 2 secs after it is called.

So the output is:


Entered thread
Exit thread

Entered thread
Exit thread

If we would not have used semaphore, the output would have been as follows due to context switching:


Entered thread
Entered thread
Exit thread
Exit thread