Home > Back-end >  How to implement global POSIX semaphore to be used by two C programs?
How to implement global POSIX semaphore to be used by two C programs?

Time:09-25

I have two C files: a.c (master) and b.c (follower).
I want to create a synchronization between master and follower using a semaphore.
According to what I have learnt I need to have a global POSIX semaphore to make this work.
How can I implement this in the b.c (follower) file using only the semaphores in a.c (master)?

Semaphore implemented for a.c file (master):

#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>

sem_t x,y;
pthread_t tid;
pthread_t writerthreads[100],readerthreads[100];
int readercount = 0, writercount = 0;

void* reader(void* param)
{
    if (writercount > 0) {
        sem_wait(&x);
        readercount  ;
        if (readercount == 1) {
            sem_wait(&y);
        }
        sem_post(&x);
        printf("%d reader is inside\n",readercount);

        //read all the files in the directory

        sleep(3);
        sem_wait(&x);
        readercount--;
        if (readercount == 0) {
            sem_post(&y);
        }
        sem_post(&x);
        printf("%d Reader is leaving\n",readercount 1);
    } else {
        printf("Nothing to view\n");
    }
    return NULL;
}

void* writer(void* param)
{
    printf("Master is trying to upload\n");
    sem_wait(&y);
    printf("Master is uploading\n");

    //create file in a directory

    sem_post(&y);
    writercount  ;
    printf("Master is leaving\n");
    return NULL;
}

int main()
{
    int a,i = 0,b;
    sem_init(&x,0,1);
    sem_init(&y,0,1);

    while (1) {
        printf("Enter 1 to View  / 2 to Upload / 3 to Exit:");
        scanf("%d",&b);
        if (b == 1) {
            pthread_create(&readerthreads[i],NULL,reader,NULL);
        } else if (b == 2) {
            pthread_create(&writerthreads[i],NULL,writer,NULL);
        } else {
            exit(0);
        }
        pthread_join(writerthreads[i],NULL);
        pthread_join(readerthreads[i],NULL);
        i  ;
    }

    return 0;
}

Semaphore in the b.c file (follower):

#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>

sem_t x,y;
pthread_t tid;
pthread_t readerthreads[100];
int readercount = 0, writercount = 0;

void* reader(void* param)
{
    if (writercount > 0) {
        sem_wait(&x);
        readercount  ;
        if (readercount == 1) {
            sem_wait(&y);
        }
        sem_post(&x);
        printf("%d Follower is inside\n",readercount);
        //read all the files in the directory
        sleep(3);
        sem_wait(&x);
        readercount--;
        if (readercount == 0) {
            sem_post(&y);
        }
        sem_post(&x);
        printf("%d Follower is leaving\n",readercount 1);
    } else {
        printf("Nothing to view\n");
    }
    return NULL;
}

int main()
{
    int a,i = 0,b;
    sem_init(&x,0,1);
    sem_init(&y,0,1);

    while (1) {
        printf("Enter 1 to View  / 3 to Exit:");
        scanf("%d",&b);
        if (b == 1) {
            pthread_create(&readerthreads[i],NULL,reader,NULL);
        } else {
            exit(0);
        }
        pthread_join(readerthreads[i],NULL);
        i  ;
    }

}

CodePudding user response:

Having two different process, you have to use named semaphore, like described here:

Share POSIX semaphore among multiple processes

So your code can be edited like

a.c

#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <fcntl.h>

sem_t *x,*y;
pthread_t tid;
pthread_t writerthreads[100],readerthreads[100];
int readercount = 0, writercount = 0;

void* reader(void* param)
{
    if (writercount > 0) {
        sem_wait(x);
        readercount  ;
        if (readercount == 1) {
            sem_wait(y);
        }
        sem_post(x);
        printf("%d reader is inside\n",readercount);

        //read all the files in the directory

        sleep(3);
        sem_wait(x);
        readercount--;
        if (readercount == 0) {
            sem_post(y);
        }
        sem_post(x);
        printf("%d Reader is leaving\n",readercount 1);
    } else {
        printf("Nothing to view\n");
    }
    return NULL;
}

void* writer(void* param)
{
    printf("Master is trying to upload\n");
    sem_wait(y);
    printf("Master is uploading\n");

    //create file in a directory

    sem_post(y);
    writercount  ;
    printf("Master is leaving\n");
    return NULL;
}

int main()
{
    int a,i = 0,b;
    x = sem_open("/semaphore_x", O_CREAT | O_EXCL, S_IRWXU | S_IRWXG  | S_IRWXO, 1);
    y = sem_open("/semaphore_y", O_CREAT | O_EXCL, S_IRWXU | S_IRWXG  | S_IRWXO, 1);
    
    if( x == NULL || y == NULL) {
        printf("Unable to open named semaphores\n");
        exit(-1);
    }

    while (1) {
        printf("Enter 1 to View  / 2 to Upload / 3 to Exit:");
        scanf("%d",&b);
        if (b == 1) {
            pthread_create(&readerthreads[i],NULL,reader,NULL);
        } else if (b == 2) {
            pthread_create(&writerthreads[i],NULL,writer,NULL);
        } else {
            sem_close(x);
            sem_close(y);
            sem_unlink("/semaphore_x");
            sem_unlink("/semaphore_y");
            exit(0);
        }
        pthread_join(writerthreads[i],NULL);
        pthread_join(readerthreads[i],NULL);
        i  ;
    }

    return 0;
}

and b.c

#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <fcntl.h>

sem_t *x,*y;
pthread_t tid;
pthread_t readerthreads[100];
int readercount = 0, writercount = 0;

void* reader(void* param)
{
    if (writercount > 0) {
        sem_wait(x);
        readercount  ;
        if (readercount == 1) {
            sem_wait(y);
        }
        sem_post(x);
        printf("%d Follower is inside\n",readercount);
        //read all the files in the directory
        sleep(3);
        sem_wait(x);
        readercount--;
        if (readercount == 0) {
            sem_post(y);
        }
        sem_post(x);
        printf("%d Follower is leaving\n",readercount 1);
    } else {
        printf("Nothing to view\n");
    }
    return NULL;
}

int main()
{
    int a,i = 0,b;
    x = sem_open("/semaphore_x", O_RDWR);
    y = sem_open("/semaphore_y", O_RDWR);

    if( x == NULL || y == NULL) {
        printf("Unable to open named semaphores\n");
        exit(-1);
    }

    while (1) {
        printf("Enter 1 to View  / 3 to Exit:");
        scanf("%d",&b);
        if (b == 1) {
            pthread_create(&readerthreads[i],NULL,reader,NULL);
        } else {
            sem_close(x);
            sem_close(y);
            exit(0);
        }
        pthread_join(readerthreads[i],NULL);
        i  ;
    }

}
  • Related