Самьюэл Алекс
Шрифт:
В листинге 4.14 показана измененная версия предыдущего примера, в которой на этот раз флаг защищается сигнальной переменной. Обратите внимание на то, что в функции
Условие, контролируемое сигнальной переменной, может быть произвольно сложным. Но перед выполнением любой операции, способной повлиять на результат проверки условия, необходимо захватить исключающий семафор, и только после этого можно посылать сигнал.
Сигнальная переменная может вообще не быть связана ни с каким условием, а служить лишь средством блокирования потока до тех пор, пока какой-нибудь другой поток не "разбудит" его. Для этой же цели может использоваться и семафор. Принципиальная разница между ними заключается в том, что семафор "запоминает" сигнал, даже если ни один поток в это время не был заблокирован, а сигнальная переменная регистрирует сигнал только в том случае, если его ожидает какой-то поток. Кроме того, семафор всегда разблокирует лишь один поток, тогда как с помощью функции
4.4.7. Взаимоблокировки двух и более потоков
Взаимоблокировка происходит, когда два (или более) потока блокируются в ожидании события, наступление которого на самом деле зависит от действий одного из заблокированных потоков. Например, если поток A ожидает изменения сигнальной переменной, устанавливаемой в потоке Б, а поток Б, в свою очередь, ждет сигнала от потока А, возникает тупиковая ситуация. Ни один из потоков никогда не пошлет сигнал другому. Необходимо тщательно избегать таких ситуаций, потому что их очень трудно обнаруживать.