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

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

Жанры

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

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

Шрифт:

18 nitems = atoi(argv[1]);

19 /* создание трех семафоров */

20 shared.mutex = Sem_open(Px_ipc_name(SEM_MUTEX), O_CREAT | O_EXCL,

21 FILE_MODE, 1);

22 shared.nempty = Sem_open(Px_ipc_name(SEM_NEMPTY), 0_CREAT | O_EXCL,

23 FILE_MODE, NBUFF);

24 shared.nstored = Sem_open(Px_ipc_name(SEM_NSTORED), O_CREAT | O_EXCL,

25 FILE_MODE, 0);

26 /* создание одного потока-производителя и одного потока-потребителя */

27 Set_concurrency(2);

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

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

30 /* ожидание завершения работы потоков */

31 Pthread_join(tid_produce, NULL);

32 Pthread_join(tid_consume, NULL);

33 /* удаление семафоров */

34 Sem_unlink(Px_ipc_name(SEM_MUTEX));

35 Sem_unlink(Px_ipc_name(SEM_NEMPTY));

36 Sem_unlink(Px_ipc_name(SEM_NSTORED));

37 exit(0);

38 }

Глобальные переменные

6-10 Потоки совместно используют буфер, содержащий NBUFF элементов, и три указателя на семафоры. Как говорилось в главе 7, мы объединяем эти данные в структуру, чтобы подчеркнуть, что семафоры используются для синхронизации доступа к буферу.

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

19-25 Мы создаем три семафора, передавая их имена функции px_ipc_name. Флаг O_EXCL мы указываем, для того чтобы гарантировать инициализацию каждого семафора правильным значением. Если после преждевременно завершенного предыдущего запуска программы остались неудаленные семафоры, мы обработаем эту ситуацию, вызвав перед их созданием sem_unlink и игнорируя ошибки. Мы могли бы проверять возвращение ошибки EEXIST при вызове sem_open с флагом O_EXCL, а затем вызывать sem_unlink и еще раз sem_open, но это усложнило бы программу. Если нам нужно проверить, что запущен только один экземпляр программы (что следует сделать перед созданием семафоров), можно обратиться к разделу 9.7, где описаны методы решения этой задачи.

Создание двух потоков

26-29 Создаются два потока, один из которых является производителем, а другой — потребителем. При запуске никакие аргументы им не передаются.

30-36 Главный поток ждет завершения работы производителя и потребителя, а затем удаляет три семафора.

ПРИМЕЧАНИЕ

Мы могли бы вызвать для каждого семафора sem_close, но это делается автоматически при завершении процесса. А вот удалить имя семафора из файловой системы необходимо явно.

В листинге 10.9 приведен текст функций produce и consume.

Листинг 10.9. Функции produce и consume

//pxsem/prodcons1.c

39 void *

40 produce(void *arg)

41 {

42 int i;

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

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

45 Sem_wait(shared.mutex);

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

47 Sem_post(shared.mutex);

48 Sem_post(shared.nstored); /* сохраняем еще 1 элемент */

49 }

50 return(NULL);

51 }

52 void *

53 consume(void *arg)

54 {

55 int i;

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

57 Sem_wait(shared.nstored); /* ожидаем появления объекта в буфере */

58 Sem_wait(shared.mutex);

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

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

61 Sem_post(shared.mutex);

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

63 }

64 return(NULL);

65 }

Производитель ожидает освобождения места в буфере

44 Производитель вызывает sem_wait для семафора nempty, ожидая появления свободного места. В первый раз при выполнении этой команды значение семафора nempty уменьшится с NBUFF до NBUFF-1.

Производитель помещает элемент в буфер

45-48 Перед помещением нового элемента в буфер производитель должен установить блокировку на семафор mutex. В нашем примере, где производитель просто сохраняет значение в элементе массива с индексом i % NBUFF, для описания состояния буфера не используется никаких разделяемых переменных (то есть мы не используем связный список, который нужно было бы обновлять каждый раз при помещении элемента в буфер). Следовательно, установка и снятие семафора mutex не являются обязательными. Тем не менее мы иллюстрируем эту технику, потому что обычно ее применение является необходимым в задачах такого рода (обновление буфера, разделяемого несколькими потоками).

После помещения элемента в буфер блокировка с семафора mutex снимается (его значение увеличивается с 0 до 1) и увеличивается значение семафора nstored. Первый раз при выполнении этой команды значение nstored изменится с начального значения 0 до 1.

Потребитель ожидает изменения семафора nstored

57-62 Если значение семафора nstored больше 0, в буфере имеются объекты для обработки. Потребитель изымает один элемент из буфера и проверяет правильность его значения, защищая буфер в момент доступа к нему с помощью семафора mutex. Затем потребитель увеличивает значение семафора nempty, указывая производителю на наличие свободных полей.

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

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

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

Стеллар. Заклинатель

Прокофьев Роман Юрьевич
3. Стеллар
Фантастика:
боевая фантастика
8.40
рейтинг книги
Стеллар. Заклинатель

Моров. Том 1 и Том 2

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

Дочь моего друга

Тоцка Тала
2. Айдаровы
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Дочь моего друга

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

Карелин Сергей Витальевич
5. Лекарь Империи
Фантастика:
городское фэнтези
аниме
героическая фантастика
попаданцы
5.00
рейтинг книги
Лекарь Империи 5

Эмиссар

Листратов Валерий
8. Ушедший Род
Фантастика:
боевая фантастика
аниме
попаданцы
7.50
рейтинг книги
Эмиссар

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

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

Тихие ночи

Владимиров Денис
2. Глэрд
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Тихие ночи

Великие мифы и легенды. 100 историй о подвигах, мире богов, тайнах рождения и смерти

Мудрова Ирина Анатольевна
Старинная литература:
мифы. легенды. эпос
5.00
рейтинг книги
Великие мифы и легенды. 100 историй о подвигах, мире богов, тайнах рождения и смерти

Низший - Инфериор. Компиляция. Книги 1-19

Михайлов Дем Алексеевич
Фантастика 2023. Компиляция
Фантастика:
боевая фантастика
5.00
рейтинг книги
Низший - Инфериор. Компиляция. Книги 1-19

Одержимый

Джеймс Питер
Top Thriller
Детективы:
триллеры
маньяки
8.67
рейтинг книги
Одержимый

Легат

Прокофьев Роман Юрьевич
6. Стеллар
Фантастика:
боевая фантастика
рпг
6.73
рейтинг книги
Легат

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

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

Глава рода

Шелег Дмитрий Витальевич
5. Живой лёд
Фантастика:
боевая фантастика
6.55
рейтинг книги
Глава рода