Operating systems and system programming Exercises (Projects)
Exercise (Project) 1 Mutual exclusion and synchronization with semaphores
POSIX semaphores come in two forms: named semaphores and unnamed semaphores. Unnamed semaphores are mainly used for synchronization between threads, and can also be used for synchronization between processes (generated by fork). Named semaphores can be used for synchronization between processes and between threads. Named semaphores mainly include sem_open, sem_post, sem_wait, sem_close, and sem_unlink.
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
sem_open() creates a new POSIX semaphore or opens an existing semaphore. The semaphore
is identified by name. The oflag argument specifies flags that control the operation of the call.
If O_CREAT is specified in oflag, then the semaphore is created if it does not already exist. If
both O_CREAT and O_EXCL are specified in oflag, then an error is returned if a semaphore
with the given name already exists. If O_CREAT is specified in oflag, then two additional
arguments must be supplied. The mode argument specifies the permissions to be placed on
the new semaphore. The value argument specifies the initial value for the new semaphore. If
O_CREAT is specified, and a semaphore with the given name already exists, then mode and
value are ignored.
int sem_wait(sem_t *sem);
sem_wait() decrements (locks) the semaphore pointed to by sem. If the semaphore's value is
greater than zero, then the decrement proceeds, and the function returns, immediately. If the
semaphore currently has the value zero, then the call blocks until either it becomes possible
to perform the decrement., or a signal handler interrupts the call.
int sem_post(sem_t *sem);
sem_post() increments (unlocks) the semaphore pointed to by sem. If the semaphore's value
consequently becomes greater than zero, then another process or thread blocked in a
sem_wait call will be woken up and proceed to lock the semaphore.
int sem_close(sem_t *sem);
sem_close() closes the named semaphore referred to by sem, allowing any resources that the
system has allocated to the calling process for this semaphore to be freed.
int sem_unlink(const char *name);
sem_unlink() removes the named semaphore referred to by name. The semaphore name is
removed immediately. The semaphore is destroyed once all other processes that have the
semaphore open close it.
Task1
Observe the situation when mutex is not used through an example (assuming the file is named no_sem.c).
Compile and link, run two processes at the same time. Observe the occurrence rules of X and O, and analyze the reasons.
Task2
Use semaphores to mutex critical resources (assuming the file is named with_sem.c)
Compile and link, run two processes at the same time. Observe the occurrence rules of X and O, and analyze the reasons.
Task3
Simulate playing chess with semaphores, where red and black take turns.
Write two C language programs, black_chess.c and red_chess.c, to simulate that red moves
and black moves in the process of playing chess respectively. Rules of movement: red first
and black second; red and black take turns to move, until the 10th step, the red side wins and
the black side loses.
Programming ideas:
Set up two synchronization semaphores.
(1) hei: The initial value is 1, which means that the black side has already moved, and it is the
red side's turn to move (meeting the chess rule "red first, black second").
(2) hong: The initial value is 0, which means that the red side has not moved yet.
Before the red chess moves, test the semaphore hei to determine whether the black side has
already moved. If so, it is the red side's turn to move, otherwise it is blocked and waits for the
black side to move. Since the initial value of hei is 1, it must be the red side go first. After the
red side moves, it sets the semaphore to notify the black side to move.
Before the black side moves, it first tests the semaphore hong to determine whether the red
side has already moved. If so, it is the turn of the black side to move, otherwise block and wait for the red side to move. Since the initial value of hong is 0, the black side will not move before the red side moves. After the black side moves, set the semaphore hei to notify the red side to move.
Submission
1. Observe the occurrence rules of X and O in Task1 and Task2.
2. Code: black_chess.c and red_chess.c
3. Report: post and analyze the results.
https://linux.die.net/man/7/sem_overview