Semaphore
- C course
- Advanced
- Lesson 35/83
- 5 min
Learn semaphores with semget and semop.
Semaphore
A semaphore is a counter used for synchronization between processes. A set is created with semget(key, nsems, flags); IPC_PRIVATE produces a new set. The initial value is set with semctl(semid, 0, SETVAL, val).
The operation is defined by struct sembuf: {sem_num, sem_op, sem_flg}. sem_op = -1 is the wait (P), sem_op = +1 is the signal (V) operation. It is applied with semop(semid, &op, 1). If the counter is zero, the -1 operation waits; the +1 operation wakes a waiter. semctl(semid, 0, IPC_RMID) removes the set.
Parent signal, child wait pattern
You can use a semaphore for event ordering. The parent zeroes it with semctl(semid, 0, SETVAL, 0) before fork. The child waits with struct sembuf op = {0, -1, 0}; semop(semid, &op, 1);; since the counter is zero, it blocks.
When the parent finishes, it signals with struct sembuf op = {0, 1, 0}; semop(semid, &op, 1);. This releases the child's -1 operation; the child wakes up and does printf. This guarantees the child runs after the parent. Cleanup is done with wait(NULL) and semctl(semid, 0, IPC_RMID).
Practice Order with a semaphore
Set up a set with int semid = semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT);. Zero it with semctl(semid, 0, SETVAL, 0);. Fork a child with pid_t pid = fork();. In the child: struct sembuf op = {0, -1, 0}; semop(semid, &op, 1);, printf("child came\n");, _exit(0);. In the parent: struct sembuf op = {0, 1, 0}; semop(semid, &op, 1);, wait(NULL);, semctl(semid, 0, IPC_RMID);.
Starter code
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <unistd.h>
// Set up semaphore set and zero it
// Fork a child to wait
// Parent signals and cleans up
int main(void) {
return 0;
}Sample solution
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void) {
int semid = semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT);
semctl(semid, 0, SETVAL, 0);
pid_t pid = fork();
if (pid == 0) {
struct sembuf op = {0, -1, 0};
semop(semid, &op, 1);
printf("child came\n");
_exit(0);
}
struct sembuf op = {0, 1, 0};
semop(semid, &op, 1);
wait(NULL);
semctl(semid, 0, IPC_RMID);
return 0;
}Expected output
child came
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Match semaphore functions
| Term | Meaning |
|---|---|
semget |
Creates set |
semop |
Applies operation |
semctl |
Sets value/removes |
sembuf |
Operation definition |
2 What does sem_op = -1 do in struct sembuf?
- Remove set
- Signal (V) operation
- Wait (P) operation Correct answer
- Set value
Explanation: sem_op = -1 is the wait (P) operation; it waits if counter is zero.
3 semop call
struct sembuf op = {0, 1, 0}; semop(semid, &op, ____);
struct sembuf op = {0, 1, 0}; semop(semid, &op, 1);
Explanation: The third parameter is the operation count; one operation takes 1.