CodeBlanks Logo Icon CodeBlanks

Semaphore

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

main.c
#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

main.c
#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

Question
struct sembuf op = {0, 1, 0}; semop(semid, &op, ____);
Answer
struct sembuf op = {0, 1, 0}; semop(semid, &op, 1);

Explanation: The third parameter is the operation count; one operation takes 1.

All lessons in Advanced