Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Martin Harvey - Threads.doc
Скачиваний:
2
Добавлен:
01.03.2025
Размер:
1.36 Mб
Скачать

Создание баб

Давайте теперь кратко познакомимся с реализацией. При создании компонент БАБ получает дескриптор окна, используя AllocateHWnd. Эта полезная функция описана в книге Danny Thorpe "Создание компонентов Delphi". Компонент БАБ довольно необычен, потому что ему требуется дескриптор окна для выполнения обработки сообщения, но в действительности он - не визуальный компонент. Возможно дать компоненту БАБ дескриптор окна, сделав его потомком TWinControl. Тем не менее это неподходящий родитель для такого компонента, поскольку БАБ не является оконным элементом. Используя AllocateHWnd, компонент может осуществлять собственную обработку сообщений, не приобретая большого количества бесполезных для него методов. Обеспечивается также некоторое улучшение эффективности благодаря тому, что процедура обработки сообщений компонента выполняет только минимальную работу, имея дело лишь с одним сообщением, и игнорируя все другие.

При создании компонент БАБ также устанавливает обработчики событий от потоков себе же. Эти обработчики выполняются в контексте потоков чтения и записи и осуществляют отправление уведомления, которое связывает потоки чтения, записи, и основной поток VCL.

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

Разрушение баб

Уничтожение компонента несколько сложнее, но использует принципы, обсужденные в предыдущих главах. Двунаправленный буфер, содержащийся в БАБ, подобен ограниченному буферу, рассмотренному в последней главе, и его разрушение проходит в три стадии. Первый этап - разблокировка всех потоков, выполняющих действия по вводу/выводу в буфер путем вызова ResetState. Второй этап - ожидание, пока все потоки не остановятся, или по крайней мере, будут в том состоянии, в котором они не выполняют больше действий с буфером. Как только это условие выполнено, может начаться третий этап, на котором уничтожаются физические структуры данных.

Разрушение БАБ, таким образом, работает так:

  • Состояние БАБ сбрасывается. При этом завершаются оба внутренних потока, затем сбрасывается состояние двунаправленного буфера, разблокируя, таким образом, все выполняющиеся операции с буфером.

  • Вызывается деструктор каждого потока. В нем освобождается семафор ожидания потока, затем поисходит ожидание завершения потока до разрушения критической секции и семафора. Некоторых читателей может удивить, что деструктор потока может вызвать WaitFor. Здесь все правильно, так как мы можем быть уверены, что поток никогда не вызовет свой собственный деструктор. В данном случае деструкторы потоков чтения и записи будут вызываться главным потоком VCL, так что зацикливания не будет.

  • Потоки чтения и записи устанавливаются в Nil, что разрешает проводить неоднократные вызовы ResetState.

  • Двунаправленный буфер разрушается, дескриптор окна освобождается.

Так как потоки внутренние для БАБ, у этих процедур очистки имеется тот положительный эффект, что деструктор БАБ может разблокировать и очистить все потоки и объекты синхронизации внутри компонента, а пользователю компонента не надо заботиться о потенциальных проблемах, присущих операциям очистки. Достаточно просто вызвать Free для БАБ. Это, очевидно, весьма желательно.

Несмотря не это, компонент все-таки дает доступ к методу ResetState. Причина в том, что компонент не контролирует другие рабочие потоки, которые могут проводить блокирующие операции с буфером. В подобных ситуациях главное приложение обязано само завершить рабочие потоки, сбросить состояние БАБ, и дождаться завершения рабочих потоков до физического разрушения БАБ.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]