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

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

Жанры

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

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

Шрифт:

■ Если размещаемый в памяти семафор совместно используется потоками одного процесса (аргумент shared при вызове sem_init равен 0), семафор обладает живучестью процесса и удаляется при завершении последнего.

■ Если размещаемый в памяти семафор совместно используется несколькими процессами (аргумент shared при вызове seminit равен 1), он должен располагаться в разделяемой памяти, и в этом случае семафор существует столько, сколько существует эта область памяти. Вспомните, что и разделяемая память Posix, и разделяемая память System V обладают живучестью ядра (табл. 1.1). Это значит, что сервер может создать область разделяемой памяти, инициализировать в ней размещаемый в памяти семафор Posix, а затем завершить работу. Некоторое время спустя один или несколько клиентов могут присоединить эту область к своему адресному пространству и получить доступ к хранящемуся в ней семафору.

Предупреждаем, что нижеследующий код не работает так, как ожидается:

sem_t mysem;

Sem_init(&mysem, 1.0); /* 2-й аргумент 1 –> используется процессами */

if (Fork == 0) { /* дочерний процесс */

 …

 Sem_post(&mysem);

}

Sem_wait(&mysem); /* родительский процесс: ожидание дочернего */

Проблема тут в том, что семафор не располагается в разделяемой памяти (см. раздел 10.12). Память, как правило, не делится между дочерним и родительским процессами при вызове fork. Дочерний процесс запускается с копией памяти родителя, но это не то же самое, что разделяемая память.

Пример

В качестве иллюстрации перепишем наш пример решения задачи производителей и потребителей из листингов 10.8 и 10.9 для использования размещаемых в памяти семафоров Posix. В листинге 10.11 приведен текст новой программы.

Листинг 10.11. Задача производителей и потребителей с использованием размещаемых в памяти семафоров

//pxsem/prodcons2.c

1 #include "unpipc.h"

2 #define NBUFF 10

3 int nitems; /* только для чтения производителем и потребителем */

4 struct { /* общие данные производителя и потребителя */

5 int buff[NBUFF];

6 sem_t mutex, nempty, nstored; /* семафоры, а не указатели */

7 } shared;

8 void *produce(void *), *consume(void *);

9 int

10 main(int argc, char **argv)

11 {

12 pthread_t tid_produce, tid_consume;

13 if (argc != 2)

14 err_quit("usage: prodcons2 <#items>");

15 nitems = atoi(argv[1]);

16 /* инициализация трех семафоров */

17 Sem_init(&shared.mutex, 0, 1);

18 Sem_init(&shared.nempty, 0, NBUFF);

19 Sem_init(&shared.nstored, 0, 0);

20 Set_concurrency(2);

21 Pthread_create(&tid_produce, NULL, produce, NULL);

22 Pthread_create(&tid_consume, NULL, consume, NULL);

23 Pthread_join(tid_produce, NULL);

24 Pthread_join(tid_consume, NULL):

25 Sem_destroy(&shared.mutex);

26 Sem_destroy(&shared.nempty):

27 Sem_destroy(&shared.nstored);

28 exit(0);

29 }

30 void *

31 produce(void *arg)

32 {

33 int i;

34 for (i = 0; i < nitems; i++) {

35 Sem_wait(&shared.nempty); /* ожидание одного свободного поля */

36 Sem_wait(&shared.mutex);

37 shared.buff[i % NBUFF] = i; /* помещение i в циклический буфер */

38 Sem_post(&shared.mutex);

39 Sem_post(&shared.nstored); /* поместили еще один элемент */

40 }

41 return(NULL);

42 }

43 void *

44 consume(void *arg)

45 {

46 int i;

47 for (i = 0; i < nitems; i++) {

48 Sem_wait(&shared.nstored); /* ожидаем появления хотя бы одного готового для обработки элемента */

49 Sem_wait(&shared.mutex);

50 if (shared.buff[i % NBUFF] != i)

51 printf("buff[*d] = *d\n", i, shared.buff[i % NBUFF]);

52 Sem_post(&shared.mutex);

53 Sem_post(&shared.nempty); /* еще одно пустое поле */

54 }

55 return(NULL);

56 }

Выделение семафоров

6 Мы объявляем три семафора типа sem_t, и теперь это сами семафоры, а не указатели на них.

Вызов sem_init

16-27 Мы вызываем sem_init вместо sem_open* а затем sem_destroy вместо sem_unlink. Вызывать sem_destroy на самом деле не требуется, поскольку программа все равно завершается.

Остальные изменения обеспечивают передачу указателей на три семафора при вызовах sem_wait и sem_post.

10.9. Несколько производителей, один потребитель

Решение в разделе 10.6 относится к классической задаче с одним производителем и одним потребителем. Новая, интересная модификация программы позволит нескольким производителям работать с одним потребителем. Начнем с решения из листинга 10.11, в котором использовались размещаемые в памяти семафоры. В листинге 10.12 приведены объявления глобальных переменных и функция main.

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

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Матабар IX

Клеванский Кирилл Сергеевич
9. Матабар
Проза:
магический реализм
5.00
рейтинг книги
Матабар IX

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
7.86
рейтинг книги
Солнечный корт

Последняя

Гусейнова Ольга Вадимовна
1. Последняя
Фантастика:
фэнтези
5.00
рейтинг книги
Последняя

Страж Кодекса

Романов Илья Николаевич
1. КО: Страж Кодекса
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Страж Кодекса

Курс 1. Сентябрь

Фокс Гарри
1. Маркатис
Фантастика:
аниме
фэнтези
сказочная фантастика
5.00
рейтинг книги
Курс 1. Сентябрь

Изгнанник Ардена

Анри Софи
Фантастика:
фэнтези
готический роман
историческое фэнтези
5.00
рейтинг книги
Изгнанник Ардена

Набирая силу

Рокотов Алексей
2. Путь князя
Фантастика:
фэнтези
5.00
рейтинг книги
Набирая силу

Тринадцатый XI

NikL
11. Видящий смерть
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Тринадцатый XI

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

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

Локки 5. Потомок бога

Решетов Евгений Валерьевич
5. Локки
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Локки 5. Потомок бога

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

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

Лекарь Империи 8

Лиманский Александр
8. Лекарь Империи
Фантастика:
попаданцы
городское фэнтези
аниме
5.00
рейтинг книги
Лекарь Империи 8

Эпоха Опустошителя. Том VIII

Павлов Вел
8. Вечное Ристалище
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Эпоха Опустошителя. Том VIII