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