C Programming

POSIX Semaphores in C

“Although every programming language has many libraries for specific purposes, the POSIX library of C has its place. It has been designed to create a great harmonization among the processes and helps a lot in using multithreading within the programs, i.e., creating multiple threads and synchronizing their execution. Within this guide today, you will see a simple illustration of using POSIX semaphores in C. For the basic C code examples, we must configure its compiler in the system. But, before that, we need to update the system as it’s a must needed step for the smooth execution of code. Thus, the query displayed in the attached snap is a must-have to update and upgrade your Linux operating system with the “apt” utility.”


This process required approximately 55 Kb of space on your Linux platform to smoothly perform the updates. If you are willing to give that much space, tap “y” to carry on. The processing will be completed in some minutes.


After the system got fully upgraded, we are going to configure the compiler of the C language in our system with the apt-get utility in the “install” command. Use “gcc” as a keyword, and that’s it.

Sem_init()

A fresh semaphore would be created when there is already an unidentified semaphore at “s”; otherwise, that already existing semaphore is going to be discarded. Throughout this method, “s” stands for a Semaphore instance that has been constructed, and shared is a signal or pennant that indicates if the semaphore may be distributed with a forked() method or otherwise. The input value serves as the semaphore’s set beginning point.

Int sem_init(sem_t* s, int shared, unsigned int value);

 

Sem_wait()

By executing a semaphore lock action upon the semaphore that is specified by “s,” the sem_wait() method holds that semaphore. The sem-wait procedure will be used to retain a semaphore or let it stand in line. Some of the previously overloaded processes awaken when some other process invokes sem_post().

int sem_wait(sem_t *s);

 

Sem_post()

When sem post is called, the value is increased, and then one of the previously backed up or awaiting operations starts running, i.e., unlocks the already locked semaphore.

int sem_post(sem_t *s);

 

Sem_destroy()

An initialized nameless semaphore “s” is destroyed employing the sem destroy() function.

int sem_destroy(sem_t *s);

 

Example

To understand the semaphores, we are going to create a C file first and then add a code to it. To create one, use the “touch” query, and you will find the new file in your system’s home folder.


Now, you have to open your empty C file with some simple editor to generate good code in it. We have been trying the “nano” editor so far, as shown in the snap beneath.


As we all know that all programming languages cannot work without libraries as these libraries hold a large number of classes, structures, functions, and objects to be utilized for overall system working. So we are starting this C program with the use of some basic and must-have libraries for the POSIX Semaphores.

To use these libraries in the code, we have to use the “#” character with the keyword “include” for each library. Right now, we have added a total of 4 libraries that are must to have in this program. Else, our program won’t work correctly. The first “stdio.h” header library is usually a must-have in every C program because it allows us to have input and output operations in the code. Therefore, we are using it to smoothly add inputs and get outputs from the code. The second library we are using here is the “pthread.h” that is a must for the use of thread programming, i.e., multithreading.

We will be using this library to create threads in a program. The next and most important library in this code is the “semaphore.h”. It has been utilized to smoothly synchronize the threads. Last but not least, the library is “unistd.h,” which enables us to use user-defined miscellaneous functions and constants. Now, we have declared the “s” semaphore using the “sem_t” built-in object of the semaphore library. Here comes the thread user-defined function “T” with no return type. It has been utilizing some built-in semaphore functions to perform synchronization. The sem_wait() function is here to hold the semaphore “s” using the “&” character.

Within the hold, the printf() statement got executed along with the “sleep” function to make this program sleep for 4 seconds. Another printf() statement displays a new message, and the sem_post() function gets executed to release the lock on semaphore “s.”

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_t s;
void* T(void * arg) {
  sem_wait(&s);
  printf("Welcome! \n");
  sleep(4);
  printf("Bye!\n");
  sem_post(&s);
 }

 

Let’s take a good look at the main() method of this C program for semaphores. The sem_init() function has been utilized here to create a new semaphore “s” that has not been distributed with a forked() method, i.e., “0”, and its starting point is set to 1. The pthread_t object from the pthread library of C got utilized to create two threads using two thread objects, o1 and o2. The printf() statement is here to display that we are going to create the first thread using the pthread_create() function at the very next line.

We have been passing the o1 thread object to this function with NULL restrictions and calling function “T” by passing it in the parameters. After a sleep of 4 seconds,  another thread got created with object o2, and the pthread_join() function is utilized here to join the threads with a main() function. The sem_destroy() function is here to destruct the “s” semaphore, and all the blocked threads will be released as well.

int main() {
  sem_init(&s, 0, 1);
  pthread_t o1, o2;
  printf("In a 1st Thread now...\n");
  pthread_create(&o1,NULL,T,NULL);
  sleep(4);
  printf("In a 2nd Thread now...\n");
  pthread_create(&o2,NULL,T,NULL);
  pthread_join(o1,NULL);
  pthread_join(o2,NULL);
  sem_destroy(&s);
  return 0;
 }

 

We are compiling the C program with the “Gcc” compiler; the “-lrt” and “-lpthread” options are utilized for executing the POSIX thread functions. On running the “.a/.out” query, the first thread got created. It goes to sleep after printing the first message.


The second thread got synchronized, and after 4 seconds, the first thread got released, and the second thread got locked for 4 seconds.


In the end, the second thread also got released.

Conclusion

That’s it about the POSIX Semaphores in C while utilizing some of its main functions to synchronize different threads. After going through this article, you will be able to understand POSIX more and more.

About the author

Kalsoom Bibi

Hello, I am a freelance writer and usually write for Linux and other technology related content