Resource Access Management using Semaphore - BunksAllowed

BunksAllowed is an effort to facilitate Self Learning process through the provision of quality tutorials.

Community

Resource Access Management using Semaphore

Share This

In this simple program, we have used a binary semaphore, though we can extend it to more semaphore variables if required.

To perform this experiment, this program can be invoked several times. The output will show the execution of the critical section.

Source code of semun.h
union semun { int val; struct semid_ds *buf; unsigned short *array; }
Source code of res_man_sem.c
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/sem.h> #include "semun.h" static int set_sem_value(void); static void del_sem_value(void); static int sem_p(void); static int sem_v(void); static int sem_id; int main(int argc, char *argv[]) { int i; int pause_time; char op_char = 'O'; srand((unsigned int) getpid()); sem_id = semget((key_t) 1234, 1, 0666 | IPC_CREAT); if (argc > 1) { if (!set_sem_value()) { fprintf(stderr, "Failed to initialize semaphore\n"); exit(EXIT_FAILURE); } op_char = 'X'; sleep(2); } for(i = 0; i < 10; i++) { if (!sem_p()) exit(EXIT_FAILURE); printf("%c", op_char);fflush(stdout); pause_time = rand() % 3; sleep(pause_time); printf("%c", op_char); fflush(stdout); if (!sem_v()) exit(EXIT_FAILURE); pause_time = rand() % 2; sleep(pause_time); } printf("\n%d - finished\n", getpid()); if (argc > 1) { sleep(10); del_sem_value(); } exit(EXIT_SUCCESS); } static int set_sem_value(void) { union semun sem_union; sem_union.val = 1; if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return (0); return (1); } static void del_sem_value(void) { union semun sem_union; if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1) fprintf(stderr, "Failed to delete semaphore\n"); } static int sem_p(void) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "sem_p failed\n"); return (0); } return (1); } static int sem_v(void) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; /* V() */ sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "sem_v failed\n"); return (0); } return (1); }
Compile the program as follow:

$ gcc res_man_sem.c -o res_man_sem
Then run two processes, the first process as a background process with argument 1 and the second process without any argument as shown below.

$./res_man_sem 1 &
$./res_man_sem


Happy Exploring!

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.