C program to apply "named" semaphore lock on share resource between independent processes

C program to apply "named" semaphore lock on share resource between independent processes

Steps to test the below code

1. create 3 ".c"  files which has the same code.
2. compile and execute all the 3 binaries at once.

the expected output with timestamps is at the end of this code.

neelkanth_surekha#cat 1.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>
#include <time.h>
#include <string.h>

/* define macro PRINTF for printf , where in PRINTF takes same arguments as printf and 
 * also prints timestamp  */
#define LOG_INIT()          time_t ltime; /* calendar time */ \
                            char *ptr;\

#define PRINTF(...)      ltime = time(NULL); /* get current cal time */ \
                            ptr = asctime( localtime(&ltime));\
                            ptr[strlen(ptr)-1] = '\0';\
                            printf("%s: ", ptr); \
                            printf(__VA_ARGS__); printf("\n");

#define SEM_NAME "neel_semaphore"
#define SEM_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
#define INITIAL_VALUE  1


void main()
{
    LOG_INIT();
     
    int sem_value = 0;

       /* Here file.txt is the shared resource. apply sem lock till it's closed by a process  */
       /* We initialize the semaphore counter to 1 (INITIAL_VALUE) */
       /* If O_CREAT  is specified in oflag, then the semaphore is created if it does not already exist.
        *      *      * If both O_CREAT and O_EXCL are specified in oflag, then an error is returned if a semaphore
        *           *           * with the given name already exists.
        *                *                */
       sem_t *semaphore = sem_open(SEM_NAME, O_CREAT , SEM_PERMS, INITIAL_VALUE);
       if (semaphore == SEM_FAILED) {
           perror("sem_open(3) error");
           exit(EXIT_FAILURE);
       }

       PRINTF("PID %ld trying to acquire semaphore", (long) getpid());

       if (!sem_getvalue(semaphore, &sem_value)) {
           PRINTF("PID %d semaphore value: %d", getpid(), sem_value);
       }

       /* check whether the semaphore is available of not.  */
       if (sem_value ==  1)
       {
           PRINTF("PID %d: I have got the semaphore %s\n", getpid(), SEM_NAME);
       } else {
           PRINTF("PID %d: Some other process has the semaphore now. SO, i will wait "
                   "till the lock is released.\n", getpid());
       }

       /* If semaphore is not available, then the code is blocked here. */
       if (sem_wait(semaphore) < 0) {
           perror("sem_wait(3) failed on child");
           exit(EXIT_FAILURE);
       }

       PRINTF("############################## CRITICAL SECTION STARTS HERE #################################");
       PRINTF("PID %d acquired semaphore\n", getpid());

       PRINTF("PID %d at this point access the shared resource like file or shared memory \n", getpid());

       /* sleep is added here to just for demo purpose so that we can visibly see the other process waiting for semaphore lock */
       sleep(10);
       PRINTF("############################## CRITICAL SECTION ENDS HERE ##################################\n");

       if (sem_post(semaphore) < 0) {
           perror("sem_post(3) error on child");
       }

       if (sem_close(semaphore) < 0)
           perror("sem_close(3) failed");
       PRINTF("PID %ld release semaphore\n", (long) getpid());


       sem_unlink(SEM_NAME);

       return;
}


Output:

neelkanth_surekha#./1 

Thu Nov 23 01:08:30 2017: PID 4139 trying to acquire semaphore
Thu Nov 23 01:08:30 2017: PID 4139 semaphore value: 1
Thu Nov 23 01:08:30 2017: PID 4139: I have got the semaphore neel_semaphore

Thu Nov 23 01:08:30 2017: ############################## CRITICAL SECTION STARTS HERE #################################
Thu Nov 23 01:08:30 2017: PID 4139 acquired semaphore

Thu Nov 23 01:08:30 2017: PID 4139 at this point access the shared resource like file or shared memory 

Thu Nov 23 01:08:40 2017: ############################## CRITICAL SECTION ENDS HERE ##################################

Thu Nov 23 01:08:40 2017: PID 4139 release semaphore

neelkanth_surekha#./2 

Thu Nov 23 01:08:31 2017: PID 4140 trying to acquire semaphore
Thu Nov 23 01:08:31 2017: PID 4140 semaphore value: 0
Thu Nov 23 01:08:31 2017: PID 4140: Some other process has the semaphore now. SO, i will wait till the lock is released.

Thu Nov 23 01:08:40 2017: ############################## CRITICAL SECTION STARTS HERE #################################
Thu Nov 23 01:08:40 2017: PID 4140 acquired semaphore

Thu Nov 23 01:08:40 2017: PID 4140 at this point access the shared resource like file or shared memory 

Thu Nov 23 01:08:50 2017: ############################## CRITICAL SECTION ENDS HERE ##################################

Thu Nov 23 01:08:50 2017: PID 4140 release semaphore

neelkanth_surekha#./3 

Thu Nov 23 01:08:32 2017: PID 4141 trying to acquire semaphore
Thu Nov 23 01:08:32 2017: PID 4141 semaphore value: 0
Thu Nov 23 01:08:32 2017: PID 4141: Some other process has the semaphore now. SO, i will wait till the lock is released.

Thu Nov 23 01:08:50 2017: ############################## CRITICAL SECTION STARTS HERE #################################
Thu Nov 23 01:08:50 2017: PID 4141 acquired semaphore

Thu Nov 23 01:08:50 2017: PID 4141 at this point access the shared resource like file or shared memory 

Thu Nov 23 01:09:00 2017: ############################## CRITICAL SECTION ENDS HERE ##################################

Thu Nov 23 01:09:00 2017: PID 4141 release semaphore