26.
Критический участок и критическая
секция. Реализация критических секций с использованием блокирующих переменных и
ее недостатки.
Важным
понятием синхронизации потоков является понятие «критической секции» программы.
Критическая секция — это часть программы, результат выполнения которой может
непредсказуемо меняться, если переменные, относящиеся к этой части программы,
изменяются другими потоками в то время, когда выполнение этой части еще не
завершено. Критическая секция всегда определяется по отношению к определенным
критическим данным, при несогласованном изменении которых могут возникнуть нежелательные
эффекты. В предыдущем примере такими критическими данными являлись записи файла
базы данных. Во всех потоках, работающих с критическими данными, должна быть
определена критическая секция. Заметим, что в разных потоках критическая секция
состоит в общем случае из разных последовательностей команд.
Самый
простой и в то же время самый неэффективный способ обеспечения взаимного
исключения состоит в том, что операционная система позволяет потоку запрещать любые прерывания на время его
нахождения в критической секции. Однако этот способ практически не применяется,
так как опасно доверять управление системой пользовательскому потоку — он может
надолго занять процессор, а при крахе потока в критической секции крах потерпит
вся система, потому что прерывания никогда не будут разрешены.
Для
синхронизации потоков одного процесса прикладной программист может использовать
глобальные блокирующие переменные. С этими переменными, к которым все потоки
процесса имеют прямой доступ, программист работает, не обращаясь к системным
вызовам ОС.
Рис. 6.1.3. Реализация критических секций с использованием блокирующих переменных
Реализация
взаимного исключения описанным выше способом имеет существенный недостаток: в
течение времени, когда один поток находится в критической секции, другой поток,
которому требуется тот же ресурс, получив доступ к процессору, будет непрерывно
опрашивать блокирующую переменную, бесполезно тратя выделяемое ему процессорное
время, которое могло бы быть использовано для выполнения какого-нибудь другого
потока. Для устранения этого недостатка во многих ОС предусматриваются
специальные системные вызовы для работы с критическими секциями.