Чтение онлайн

ЖАНРЫ

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:

11 return(-1);

12 if ((semid = semget(key, 1, SVSEM_MODE)) == –1)

13 return(-1);

14 if (semctl(semid, 0, IPC_RMID) == –1)

15 return(-1);

16 return(0);

17 }

Получение ключа System V по полному имени

8-16 Функция ftok преобразует полное имя файла в ключ System V IPC. После этого вспомогательный файл удаляется вызовом unlink (именно в этом месте кода, на тот случай, если одна из последующих функций

вернет ошибку). Затем мы открываем семафор System V вызовом semget и удаляем его с помощью команды IPC_RMID для semctl.

Функция sem_post

В листинге 10.41 приведен текст функции sem_post, которая увеличивает значение семафора.

11-16 Мы вызываем semop с операцией, увеличивающей значение семафора на 1.

Листинг 10.41. Функция sem_post

//my_pxsem_svsem/sem_post.с

1 #include "unpipc.h"

2 #include "semaphore.h"

3 int

4 mysem_post(mysem_t *sem)

5 {

6 struct sembuf op;

7 if (sem->sem_magic != SEM_MAGIC) {

8 errno * EINVAL;

9 return(-1);

10 }

11 op.sem_num = 0;

12 op.sem_op = 1;

13 op.sem_flg = 0;

14 if (semop(sem->sem_semid, &op, 1) < 0)

15 return(-1);

16 return(0);

17 }

Функция sem_wait

Следующая функция приведена в листинге 10.42; она называется sem_wait и ожидает изменения значения семафора с нулевого на ненулевое, после чего уменьшает значение семафора на 1.

11-16 Мы вызываем semop с операцией, уменьшающей значение семафора на 1.

Листинг 10.42. Функция sem_wait

//my_pxsem_svsem/sem_wait.c

1 #include "unpipc.h"

2 #include "semaphore.h"

3 int

4 mysem_wait(mysem_t *sem)

5 {

6 struct sembuf op;

7 if (sem->sem_magic != SEM_MAGIC) {

8 errno = EINVAL;

9 return(-1);

10 }

11 op.sem_num = 0;

12 op.sem_op = –1;

13 op.sem_flg = 0;

14 if (semop(sem->sem_semid, &op, 1) < 0)

15 return(-1);

16 return(0);

17 }

Функция sem_trywait

В листинге 10.43 приведен текст нашей функции sem_trywait, которая представляет собой неблокируемую версию sem_wait.

13 Единственное отличие от функции sem_wait из листинга 10.42 заключается в том, что флагу sem_flg присваивается

значение IPC_NOWAIT. Если операция не может быть завершена без блокирования вызвавшего потока, функция semop возвращает ошибку EAGAIN, а это именно тот код, который должен быть возвращен sem_trywait, если операция не может быть завершена без блокирования потока.

Листинг 10.43. Функция sem_trywait

//my_pxsem_svsem/sem_trywait.c

1 #include "unpipc.h"

2 #include "semaphore.h"

3 int

4 mysem_trywait(mysem_t *sem)

5 {

6 struct sembuf op;

7 if (sem->sem_magic != SEM_MAGIC) {

8 errno = EINVAL;

9 return(-1);

10 }

11 op.sem_num = 0;

12 op.sem_op = –1;

13 op.sem_flg = IPC_NOWAIT;

14 if (semop(sem->sem_semid, &op, 1) < 0)

15 return(-1);

16 return(0);

17 }

Функция sem_getvalue

Последняя функция приведена в листинге 10.44. Это функция sem_getvalue, возвращающая текущее значение семафора.

11-14 Текущее значение семафора получается отправкой команды GETVAL функции semctl.

Листинг 10.44. Функция sem_getvalue

//my_pxsem_svsem/sem_getvalue.с

1 #include "unpipc.h"

2 #include "semaphore.h"

3 int

4 mysem_getvalue(mysem_t *sem, int *pvalue)

5 {

6 int val;

7 if (sem->sem_magic != SEM_MAGIC) {

8 errno = EINVAL;

9 return(-1);

10 }

11 if ((val = semctl(sem->sem_semid, 0, GETVAL)) < 0)

12 return(-1);

13 *pvalue = val;

14 return(0);

15 }

10.17. Резюме

Семафоры Posix представляют собой семафоры-счетчики, для которых определены три основные операции:

1. Создание семафора.

2. Ожидание изменения значения семафора на ненулевое и последующее уменьшение значения.

3. Увеличение значения семафора на 1 и возобновление выполнения всех процессов, ожидающих его изменения.

Семафоры Posix могут быть именованными или неименованными (размещаемыми в памяти). Именованные семафоры всегда могут использоваться отдельными процессами, тогда как размещаемые в памяти должны для этого изначально планироваться как разделяемые между процессами. Эти типы семафоров также отличаются друг от друга по живучести: именованные семафоры обладают по меньшей мере живучестью ядра, тогда как размещаемые в памяти обладают живучестью процесса.

Поделиться с друзьями: