5.7. Пример использования объектов синхронизации POSIX
Для борьбы с этим явлением вводится объект mutex, который фактически состоит из пары: булевского
семафора и идентификатора задачи - текущего владельца семафора (т.е. той задачи, которая успешно
вызвала функцию взять и стала владельцем разделяемого ресурса). Для доступа к объекту mutex m
определены три примитивные операции:
•65535 Lock(m) - блокировать mutex m , если m уже заблокирован другой задачей, то эта операция
переводит задачу в состояние ожидания разблокирования пг;
•65535 Unlock(m) - разблокировать mutex m , (если m ожидается другой задачей, то она может
быть активизирована, удалена из очереди ожидания и может вытеснить текущую задачу, например,
если ее приоритет выше); если вызвавшая эту операцию задача не является владельцем пг, то операция
не имеет никакого эффекта;
•65535 TryLock(m) - попробовать блокировать mutex m , если m не блокирован, то эта операция
эквивалентна Lock(m), иначе возвращается признак неудачи.
Эти операции неделимы, т.е. переключение задач во время их исполнения запрещено. 5.6.2. Объекты
синхронизации типа condvar
Объект синхронизации типа condvar дает возможность задаче ожидать выполнения некоторых
условий. Фактически он состоит из объекта - события Е (см. раздел 5.2), с одним отличием: при
поступлении события (посредством функции Send) только одна из очереди ожидающих события задач
активизируется. Для доступа к объекту condvar Е определены три примитивные операции:
• Wait(E, m ) (где m типа mutex) - производит следующие действия (первые два из них неделимы, т.е.
переключение задач во время их исполнения запрещено):
—65535 вызвать Unlock(m) для текущей задачи (т.е. вызвавшей эту операцию),
—65535 вызвать Wait(E),
—65535 вызвать Lock(m);
•65535 Signal(E) - вызвать Send(E);
•65535 Broadcast(E) - вызвать Send(E) и активизировать все ожидающие задачи (т.е. тот же эффект,
что и для функции Send, описанной в разделе 5.2.
5.7. Пример использования объектов синхронизации POSIX
Приводимая ниже программа считывает строку со стандартного ввода и выводит ее на стандартный
вывод. Для чтения строки и для ее вывода создаются две задачи (thread), кодом для которых являются
функции reader и writer соответственно. Поскольку задачи работают в том же адресном пространстве,
что и создавший их процесс, то они автоматически разделяют все переменные, включая буфер сообщений
msgbuf. Для организации взаимного исключения при доступе к критическим разделяемым ресурсам
(переменным done, msglen, msgbuf) используется объект синхронизации mutex mutx.
♦include <stdio.h>
♦include <pthread.h>
/* Компиляция в POSIX-совместимых системах (например, Linux):
*/
/* сс <имя_файла> -Ipthread
*/
♦define BUF_LEN 256
31