- •«Объединения» - завершение потоков
- •«Барьеры»
- •Механизм семафоров
- ••При создании семафора S с ним связывается очередь заблокированных процессов; очередь обслуживается в
- •Обеспечение взаимного исключения
- •Общий (счетный) семафор
- •Пример: «Поставщик-Потребитель»
- •«Поставщик-Потребитель» - реализация
- •«Поставщик-Потребитель» - комментарии
- •Недостатки механизма семафоров
- •Семафоры (POSIX)
- •Мьютекс (mutual exclusion)
- •Попытка вызова unlock() «не владельцем»
- •Мьютекс - инициализация и захват
- •Освобождение
- •Мьютекс QNX (POSIX)
- •Мьютекс и инверсия приоритетов
- •Условные переменные
- •Механизм сообщений (QNX)
- •smsg
- •Пример - Клиент
- •Пример - Сервер
«Объединения» - завершение потоков
thread_0 thread_1
Синхронизация .
void* thread_0 (void* args)
{
. . .
}
main void* thread_1 (void* args)
{
. . .
}
int main()(int argc, char *argv[]) { pthread_t thread_id_1, thread_id_2;
. . .
pthread_create(&thread_id_1, NULL, &thread_0, NULL); pthread_create(&thread_id_2, NULL, &thread_1, NULL);
. . .
pthread_join(thread_id_1, NULL); pthread_join(thread_id_2, NULL);
. . .
}
int pthread_join( pthread_t thread, void** value_ptr );
12. Механизмы синхронизации 2015 v.01 |
1 |
«Барьеры»
pthread_barrier_t barrier;
int pthread_barrier_init(pthread_barrier_t* barrier, pthread_barrierattr_t* attr, unsigned int count);
int pthread_barrier_wait(pthread_barrier_t* barrier).
Клиент Сервер
Ожидает |
|
создания |
|
«канала» |
Chanal_ID |
|
|
|
Создает |
|
«канал» |
int chid; pthread_barrier_t barrier;
void* Client(void* args){
. . .
pthread_barrier_wait(&barrier);
. . .
coid = ConnectAttach(0, getpid(), chid, 0, 0);
. . .
}
int main(int argc, char *argv[]) {
. . .
pthread_barrier_init(&barrier, NULL, 2);
chid = ChannelCreate(0); pthread_create(&client, NULL, &Client, NULL); pthread_barrier_wait(&barrier);
. . .
}
12. Механизмы синхронизации |
2015 v.01 |
2 |
Механизм семафоров
История вопроса
( Эдсгер Дейкстра (1930-2002) Взаимодействующие последовательные процессы.
В кн. Языки программирования. п. р. Женюи, Москва, Мир, 1972)
Предполагается возможность создать переменную S – двоичный семафор, способную принимать только два значения – «0» или «1».
Над такой переменной допускались две операции - P(S) и V(S)
P(S):
if (S = 0) then wait(S = 1); S := 0;
V(S):
S := 1;
12. Механизмы синхронизации |
2018 v.01 |
3 |
•При создании семафора S с ним связывается очередь заблокированных процессов; очередь обслуживается в соответствии с определенной дисциплиной, не допускающей бесконечного ожидания процесса (например, FIFO)
•При S = 0 операция ждать(S>0) блокирует задачу, вызвавшую операцию P(S) и ставит ее в очередь до момента выполнения условия S>0;
•При выполнении операции V(S)активизируется первая задача из очереди; продолжение этой задачи происходит с действия S=0 приостановленной P– операции
•P и V операции над семафором S являются неделимыми (могут выполняться только одной задачей)
12. Механизмы синхронизации |
2018 v.01 |
4 |
Обеспечение взаимного исключения
S = ДвСемафор(1);
Ri: loop P(S); КС_I; V(S);
Остальное_I endloop;
Parbegin
R1;. . .Rn;
Parend.
•P и V операции неделимы; т.е. выполнять S.P() может только одна задача ;
•Если одна из задач выполнила P(S) и вошла в свою КС, то S=0 и все остальные задачи, выполняющие P(S), будут блокироваться. Взаимное исключение обеспечено
•При выполнении V(S) соблюдается очередность, т.е. никто не будет ждать бесконечно долго
12. Механизмы синхронизации |
2018 v.01 |
5 |
Общий (счетный) семафор
S = ОбСемафор(m, n); P(S):
if (S = 0) then wait(S > 0); S := S - 1;
V(S):
if (S < n) then S := S + 1;
•При описании: m - начальное и n - максимальное значения
•При S > 0 каждый вызов P(S) уменьшает значение S на единицу, вызвавшая P(S) задача не блокируется
•При S = 0 все последующие вызовы P(S) будут блокировать вызывающую задачу и ставить ее в очередь.
•При S > 0 операция V(S) просто увеличивает значение семафора, не допуская при этом превышения максимального значения
12. Механизмы синхронизации |
2018 v.01 |
6 |
Пример: «Поставщик-Потребитель»
Поставщик A Потребитель
Поставщик: производит единицы информации и записывает их в буфер А, размер которого N
Потребитель: читает и обрабатывает информацию из буфера А Требуется реализовать задачи Поставщик и Потребитель таким образом,
чтобы выполнялись условия:
а) Поставщик не может записывать в полный буфер; б) Потребитель не может читать из пустого буфера;
в) одновременные запись и чтение недопустимы
12. Механизмы синхронизации |
2018 v.01 |
7 |
«Поставщик-Потребитель» - реализация
Доступ = ДвСемафор(1); Полон = ОбСемафор(N,N); Пуст = ОбСемафор(0,N);
Поставщик: |
Потребитель: |
|
loop |
loop |
|
|
Производство; |
P(Пуст); |
(*) |
P(Полон); |
P(Доступ); |
(**) |
P(Доступ); |
Чтение_из_буфера; |
|
Запись_в_буфер; |
V(Доступ); |
|
V(Доступ); |
V(Полон); |
|
V(Пуст); |
Обработка; |
endloop. |
endloop. |
Parbegin Поставщик; Потребитель Parend;
12. Механизмы синхронизации |
2018 v.01 |
8 |
«Поставщик-Потребитель» - комментарии
Проследим работу схемы в следующих ситуациях:
а) Поставщик пишет, Потребитель остановлен в действии Обработка. Перед каждой записью в буфер значение семафора Полон уменьшается на 1. При полном буфере Поставщик
блокируется на семафоре Полон в операции P(Полон)
б) Потребитель читает, Поставщик остановлен в действии Производство. Перед каждым чтением уменьшается значение семафора Пуст. При пустом буфере Потребитель блокируется в операции P(Пуст)
в) Взаимное исключение доступа обеспечивается семафором Доступ г) Если поменять местами (*)и (**), то может возникнуть блокировка.
12. Механизмы синхронизации |
2018 v.01 |
9 |
Недостатки механизма семафоров
•Низкий уровень, слабая защищенность от ошибок при программировании
•Возможность использования P() и V() над одним семафором из разных задач (семафор S может быть установлен в 0 в одной задаче, а в 1 – в другой, см. задачу «Поставщик-Потребитель»)
•Возможность вызова V-операции над семафором без предварительного вызова P-операции
•Не позволяет реализовать протокол наследования приоритетов (не определен процесс-«владелец» семафора)
12. Механизмы синхронизации |
2018 v.01 |
10 |