10.3. Критические разделы |
Вверх Предыдущий Следующий |
При программировании потоков иногда необходимо избегать одновременного доступа к некоторым ресурсам, или одновременного вызова подпрограммы из двух потоков. Это может быть сделано с использованием Critical Section (критический раздел). Менеджер кучи FPC использует критические разделы, если включена многопоточность. Тип TRTLCriticalSection – это непрозрачный (Opaque) тип. Он зависит от операционной системы, на которой выполняется код. Он должен быть инициализирован перед первым использованием, и должен быть освобождён, когда в нём больше нет необходимости. Для защиты участка кода должен быть сделан вызов EnterCriticalSection: когда этот вызов возвращает результат, это гарантирует, что текущий поток – это единственный поток, выполняемый в последующем коде. Для гарантии этого данный вызов может приостановить текущий поток на некоторое время. Когда защищённый код завершится, должна быть вызвана LeaveCriticalSection: она включает другие потоки и разрешает их выполнение в защищённом коде. Чтобы минимизировать время ожидания для других потоков, важно создавать и удерживать защищённый блок как можно меньше. Объявления этих подпрограмм следующие: procedure InitCriticalSection(var cs: TRTLCriticalSection); Смысл этих подпрограмм также очевиден: InitCriticalSection – инициализирует критический раздел. Это вызов нужно делать перед использованием EnterCrititicalSection или LeaveCriticalSection. DoneCriticalSection – освобождает ресурсы, связанные с критическим разделом. После этого вызова ни EnterCrititicalSection ни LeaveCriticalSection не могут быть использованы. EnterCriticalSection – когда этот вызов возвращает результат, вызывающий поток является единственным выполняемым потоком между вызовом EnterCriticalSection и последующим вызовом LeaveCriticalsection. LeaveCriticalSection – сигнализирует о том, что защищённый код может выполняться другими потоками. Учтите, что вызов LeaveCriticalsection должен быть выполнен. Если этого не сделать, то все другие потоки не смогут выполнять код в критическом разделе. Поэтому рекомендуется заключать критический раздел в блок Try..finally. Обычно код выглядит следующим образом: Var |