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

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

Жанры

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

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

Шрифт:

solaris % semwait /test2& еще один фоновый процесс

[2] 4263

solaris % semgetvalue /test2

value 0 и для двух ожидающих процессов значение остается нулевым

solaris % sempost /test2 выполняем операцию post

pid 4257 has semaphore, value = 0 вывод программы semwait

value = 0

solaris % sempost /test2

pid 4263 has semaphore, value = 0 вывод программы semwait

value = 0

Можно заметить отличие по сравнению с результатами выполнения той же последовательности команд в Digital Unix 4.0B: после изменения значения семафора управление сразу же передается ожидающему изменения семафора процессу.

10.6. Задача производителей и потребителей

В разделе 7.3 мы описали суть задачи производителей и потребителей и привели несколько возможных ее решений, в которых несколько потоков-производителей заполняли массив, который обрабатывался одним потоком-потребителем.

1. В нашем первом варианте решения (раздел 7.2) потребитель запускался только после завершения работы производителей, поэтому мы могли решить проблему синхронизации, используя единственное взаимное исключение для синхронизации производителей.

2. В следующем варианте решения (раздел 7.5) потребитель запускался до завершения работы производителей, поэтому требовалось использование взаимного исключения (для синхронизации производителей) вместе с условной переменной и еще одним взаимным исключением (для синхронизации потребителя с производителями).

Расширим постановку задачи производителей и потребителей, используя общий буфер в качестве циклического: заполнив последнее поле, производитель (buff[NBUFF-1]) возвращается к его началу и заполняет первое поле (buff[0]), и потребитель действует таким же образом. Возникает еще одно требование к синхронизации: потребитель не должен опережать производителя. Мы все еще предполагаем, что производитель и потребитель представляют собой отдельные потоки одного процесса, но они также могут быть и просто отдельными процессами, если мы сможем создать для них общий буфер (например, используя разделяемую память, часть 4).

При использовании общего буфера в качестве циклического код должен удовлетворять трем требованиям:

1. Потребитель не должен пытаться извлечь объект из буфера, если буфер пуст.

2. Производитель не должен пытаться поместить объект в буфер, если последний полон.

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

Наше решение использует три семафора:

1. Бинарный семафор с именем mutex защищает критические области кода: помещение данных в буфер (для производителя) и изъятие данных из буфера (для потребителя). Бинарный семафор, используемый в качестве взаимного исключения, инициализируется единицей. (Конечно, мы могли бы воспользоваться и обычным взаимным исключением вместо двоичного семафора. См. упражнение 10.10.)

2. Семафор-счетчик с именем nempty подсчитывает количество свободных полей в буфере. Он инициализируется значением, равным объему буфера (NBUFF).

3. Семафор-счетчик с именем nstored подсчитывает количество заполненных полей в буфере. Он инициализируется нулем, поскольку изначально буфер пуст.

Рис. 10.7. Состояние буфера и двух семафоров-счетчиков после инициализации

На рис. 10.7 показано состояние буфера и двух семафоров-счетчиков после завершения инициализации. Неиспользуемые элементы массива выделены темным.

В нашем примере производитель помещает в буфер целые числа от 0 до NLOOP-1 (buff[0] = 0, buff[1] = 1), работая с ним как с циклическим. Потребитель считывает эти числа и проверяет их правильность, выводя сообщения об ошибках в стандартный поток вывода.

На рис. 10.8 изображено состояние буфера и семафоров-счетчиков после помещения в буфер трех элементов, но до изъятия их потребителем.

Рис. 10.8. Буфер и семафоры после помещения в буфер трех элементов

Предположим, что потребитель изъял один элемент из буфера. Новое состояние изображено на рис. 10.9.

Рис. 10.9. Буфер и семафоры после удаления первого элемента из буфера

В листинге 10.8 приведен текст функции main, которая создает три семафора, запускает два потока, ожидает их завершения и удаляет семафоры.

Листинг 10.8. Функция main для решения задачи производителей и потребителей с помощью семафоров

//pxsem/prodcons1.с

1 #include "unpipc.h"

2 #define NBUFF 10

3 #define SEM_MUTEX "mutex" /* аргументы px_ipc_name */

4 #define SEM_NEMPTY "nempty"

5 #define SEM_NSTORED "nstored"

6 int nitems; /* read-only для производителя и потребителя */

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

8 int buff[NBUFF];

9 sem_t *mutex, *nempty, *nstored;

10 } shared;

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

12 int

13 main(int argc, char **argv)

14 {

15 pthread_t tid_produce, tid_consume;

16 if (argc != 2)

17 err_quit("usage: prodcons1 <#items>");

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

На границе империй. Том 3

INDIGO
3. Фортуна дама переменчивая
Фантастика:
космическая фантастика
5.63
рейтинг книги
На границе империй. Том 3

Моров. Том 3

Кощеев Владимир
2. Моров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Моров. Том 3

Мл. сержант. Назад в СССР. Книга 3

Гаусс Максим
3. Второй шанс
Фантастика:
альтернативная история
6.40
рейтинг книги
Мл. сержант. Назад в СССР. Книга 3

Весь цикл «Десантник на престоле». Шесть книг

Ланцов Михаил Алексеевич
Десантник на престоле
Фантастика:
альтернативная история
8.38
рейтинг книги
Весь цикл «Десантник на престоле». Шесть книг

Кодекс Императора III

Сапфир Олег
3. Кодекс Императора
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Императора III

Бастард Императора

Орлов Андрей Юрьевич
1. Бастард Императора
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Бастард Императора

Московское золото или нежная попа комсомолки. Часть Вторая

Хренов Алексей
2. Летчик Леха
Фантастика:
попаданцы
5.00
рейтинг книги
Московское золото или нежная попа комсомолки. Часть Вторая

Я снова князь. Книга XXIII

Дрейк Сириус
23. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я снова князь. Книга XXIII

Неучтенный элемент. Том 11

NikL
11. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 11

Последний Паладин. Том 13

Саваровский Роман
13. Путь Паладина
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 13

Сапер

Вязовский Алексей
1. Сапер
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.29
рейтинг книги
Сапер

Кодекс Охотника

Винокуров Юрий
1. Кодекс Охотника
Фантастика:
фэнтези
юмористическое фэнтези
попаданцы
боевая фантастика
5.00
рейтинг книги
Кодекс Охотника

Аспирант

Поселягин Владимир Геннадьевич
3. Рунный маг
Фантастика:
боевая фантастика
4.50
рейтинг книги
Аспирант

Атаман царского Спецназа

Корчевский Юрий Григорьевич
Боевая фантастика Ю. Корчевского
Фантастика:
боевая фантастика
попаданцы
альтернативная история
6.00
рейтинг книги
Атаман царского Спецназа