Today a tutorial to learn how to use semget(), semctl() and semop() system calls.
/* semaphore1.c */ #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include <sys/types.h> int main(int ac, char *av[]) { key_t key; int sem_id; void *addr; struct sembuf sb; if (ac != 2) printf("Usage %s pathname\n", av[0]); if ((key = ftok(av[1], 0)) == -1) fprintf(stderr, "Error: '%s'. %s\n", av[1], strerror(errno)); else printf("key = %d\n", key); sem_id = semget(key, 2, SHM_R | SHM_W); if (sem_id == -1) { sem_id = semget(key, 2, IPC_CREAT | SHM_R | SHM_W); printf("sem_id = %d\n", sem_id); semctl(sem_id, 0, SETVAL, 10); } else { printf("sem_id already created -> %d\n", sem_id); sb.sem_num = 0; sb.sem_flg = 0; sb.sem_op = -1; semop(sem_id, &sb, 1); printf("Value = %d\n", semctl(sem_id, 0, GETVAL)); } return (EXIT_SUCCESS); }
/* semaphore2.c */ #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include <sys/types.h> int main(int ac, char *av[]) { key_t key; int sem_id; void *addr; struct sembuf sb; if (ac != 2) printf("Usage %s pathname\n", av[0]); if ((key = ftok(av[1], 0)) == -1) fprintf(stderr, "Error: '%s'. %s\n", av[1], strerror(errno)); else printf("key = %d\n", key); sem_id = semget(key, 2, SHM_R | SHM_W); if (sem_id == -1) { sem_id = semget(key, 2, IPC_CREAT | SHM_R | SHM_W); printf("sem_id = %d\n", sem_id); semctl(sem_id, 0, SETVAL, 10); } else { printf("sem_id already created -> %d\n", sem_id); sb.sem_num = 0; sb.sem_flg = 0; sb.sem_op = 1; semop(sem_id, &sb, 1); printf("Value = %d\n", semctl(sem_id, 0, GETVAL)); } return (EXIT_SUCCESS); }
Let's compile our both program:
$ gcc semaphore1.c -o sem1 $ gcc semaphore2.c -o sem2
We can now open 2 terminals (2 windows) to test that we can interact on the same data with 2 different process.
In the first terminal, execute the first :
$ ./sem1 /home
The result will be something like that:
key = 327682 sem_id = 393216
$ ./sem1 /home
key = 327682 sem_id already created -> 393216 Result = 9
key = 327682 sem_id already created -> 393216
$ gcc semaphore2.c -o sem2 ; ./sem2 /home
key = 327682 sem_id already created -> 393216 Result = 0
Add new comment