Листинг 11.6. Блокировка файлов с помощью семафоров System V
//lock/locksvsem.c
1 #include "unpipc.h"
2 #define LOCK_PATH "/tmp/svsemlock"
3 #define MAX_TRIES 10
4 int semid, initflag;
5 struct sembuf postop, waitop;
6 void
7 my_lock (int fd)
8 {
9 int oflag, i;
10 union semun arg;
11 struct semid_ds seminfo;
12 if (initflag == 0) {
13 oflag = IPC_CREAT | IPC_EXCL | SVSEM_MODE;
14 if ((semid = semget(Ftok(LOCK_PATH, 0), 1, oflag)) >= 0) {
15 /* этот процесс создал семафор первым, он же его и инициализирует */
16 arg.val = 1;
17 Semctl(semid, 0, SETVAL, arg);
18 } else if (errno == EEXIST) {
19 /* семафор создан другим процессом, убедимся, что он проинициализирован */
20 semid = Semget(Ftok(LOCK_PATH, 0), 1, SVSEM_MODE);
21 arg.buf = &seminfo;
22 for (i = 0; i < MAX_TRIES; i++) {
23 Semctl(semid, 0, IPC_STAT, arg);
24 if (arg.buf->sem_otime != 0)
25 goto init;
26 sleep(1);
27 }
28 err_quit("semget OK, but semaphore not initialized");
29 } else
30 err_sys("semget error");
31 init:
32 initflag = 1;
33 postop.sem_num = 0; /* инициализируем две структуры semop()*/
34 postop.sem_op = 1;
35 postop.sem_flg = SEM_UNDO;
36 waitop.sem_num = 0;
37 waitop.sem_op = –1;
38 waitop.sem_flg = SEM_UNDO;
39 }
40 Semop(semid, &waitop, 1); /* уменьшим на 1 */
41 }
42 void
43 my_unlock(int fd)
44 {
45 Semop(semid, &postop, 1); /* увеличим на 1*/
46 }