Средства синхронизации потоков

Возможными вариантами решения проблемы являются четыре объекта, которые разработаны специально для синхронизации. Это такие объекты как событие, взаимное исключение, семафор и таймер. Помимо этого можно организовать ожидание и других объектов, дескриптор которых используется в основном для иных целей, но может применяться и для ожидания. К ним относятся: процесс, поток, оповещение об изменении в файловой системе и консольный ввод.

Событие - простейший выбор для задач синхронизации. Класс TEvent (событие) имеет два важных метода: setEvent – перевод объекта в активное состояние и ResetEvent – перевод в пассивное состояние. Конструктор события имеет следующий вид:

constructor Create(EventAttributes: PSecurityAttributes; ManualReset,

InitialState: Boolean; const Name: string);

где параметр initialstate - начальное состояние объекта; ManualReset - способ его перевода в пассивное состояние.

Если этот параметр равен True, событие должно быть переведено в пассивное состояние вручную. Иначе событие сбрасывается по мере того, как стартует хоть один поток, ждавший данный объект.

Взаимное исключение позволяет владеть ресурсом в данное время одному из потоков. Класс, инкапсулирующий взаимное исключение – TMutex. Конструктор: constructor Create (const Name: string); задает имя создаваемого объекта. Первоначально объект не принадлежит никому. Семафор подобен взаимному исключению. Разница между ними состоит в том, что семафор может управлять количеством потоков, имеющим к нему доступ. Семафор устанавливается на максимальное число потоков, к которым разрешен доступ. При достижении количества потоков этого максимума, последующие потоки будут приостановлены, В Delphi можно использовать также объект типа критическая секция.

Критические секции подобны взаимным исключениям, однако между ними существуют два главных отличия:

- взаимные исключения в отличие от критических секций могут быть совместно использованы потоками в различных процессах;

- если критическая секция принадлежит другому потоку, ожидающий поток блокируется вплоть до освобождения критической секции. В отличие от этого, взаимное исключение разрешает продолжение по истечении тайм-аута.

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