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

на главную - закладки

Жанры

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

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

Шрифт:

Функция 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 могут быть именованными или неименованными (размещаемыми в памяти). Именованные семафоры всегда могут использоваться отдельными процессами, тогда как размещаемые в памяти должны для этого изначально планироваться как разделяемые между процессами. Эти типы семафоров также отличаются друг от друга по живучести: именованные семафоры обладают по меньшей мере живучестью ядра, тогда как размещаемые в памяти обладают живучестью процесса.

Задача производителей и потребителей является классическим примером для иллюстрации использования семафоров. В этой главе первое решение состояло из одного потока-производителя и одного потока-потребителя; второе решение имело нескольких производителей и одного потребителя, а последнее решение допускало одновременную работу и нескольких потребителей. Затем мы показали, что классическая задача двойной буферизации является частным случаем задачи производителей и потребителей с одним производителем и одним потребителем.

В этой главе было приведено три примера возможной реализации семафоров Posix. Первый пример был самым простым, в нем использовались каналы FIFO, а большая часть забот по синхронизации ложилась на ядро (функции read и write). Следующая реализация использовала отображение файлов в память (аналогично реализации очередей сообщений Posix из раздела 5.8), а также взаимное исключение и условную переменную (для синхронизации). Последняя реализация была основана на семафорах System V и представляла собой, по сути, удобный интерфейс для работы с ними.

Поделиться:
Популярные книги

Черный маг императора

Герда Александр
1. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Черный маг императора

Брак по-драконьи

Ардова Алиса
Фантастика:
фэнтези
8.60
рейтинг книги
Брак по-драконьи

Наследник

Шимохин Дмитрий
1. Старицкий
Приключения:
исторические приключения
5.00
рейтинг книги
Наследник

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Варяг

Мазин Александр Владимирович
1. Варяг
Фантастика:
альтернативная история
9.10
рейтинг книги
Варяг

Горизонт Вечности

Вайс Александр
11. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Горизонт Вечности

Звездная Кровь. Экзарх III

Рокотов Алексей
3. Экзарх
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Экзарх III

Законы рода

Мельник Андрей
1. Граф Берестьев
Фантастика:
фэнтези
боевая фантастика
аниме
5.00
рейтинг книги
Законы рода

На границе империй. Том 10. Часть 6

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 6

Хозяин теней 2

Демина Карина
2. Громов
Фантастика:
аниме
попаданцы
фэнтези
7.00
рейтинг книги
Хозяин теней 2

Избрание сочинения в трех томах. Том второй

Кочетов Всеволод Анисимович
Проза:
советская классическая проза
5.00
рейтинг книги
Избрание сочинения в трех томах. Том второй

Изгои

Владимиров Денис
5. Глэрд
Фантастика:
фэнтези
боевая фантастика
5.00
рейтинг книги
Изгои

Бастард рода Неллеров. Книга 1

Усов Серг
1. Бастард рода Неллеров
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Бастард рода Неллеров. Книга 1

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель