ВУЗ:
Составители:
Рубрика:
12
4. Синхронизация потоков
Как уже упоминалось , при доступе потоков к общим ресурсам (глобаль-
ным данным, одному и тому же файлу, DLL, коммуникационному порту и т. п .)
возникают коллизии. Предотвратить коллизии можно с помощью различных
средств синхронизации. Чаще всего для этой цели используются : критические
секции, исключающие семафоры (мьютексы ), обычные семафоры, события. Все
упомянутые механизмы основаны на блокировке доступа к ресурсу , пока этот ре-
сурс занят каким - либо потоком .
Рассмотрим более подробно механизм критической секции, ограничив -
шись его реализацией на базе функций API Win32 (как обычно, в Delphi имеются
аналогичные классы - надстройки). Участок кода, содержащий потенциально
опасные обращения к ресурсу , помечается как «критическая секция» . Перед вхо-
дом в критическую секцию проверяется глобальная запись типа TRTLCriticalSec-
tion (структуру записи см . в файле ..\borland\delphi4\source\rtl\win\windows.pas), в
которой отмечено, выполняется ли критическая секция в данный момент времени
каким - либо другим потоком. Если секция не занята, поток допускается к работе.
В начале критической секции необходимо вызвать подпрограмму API
procedure EnterCriticalSection (sect:TRTLCriticalSection);
которая проверяет состояние записи sect: TRTLCriticalSection и, если в за-
писи секция помечена как занятая другим потоком, приостанавливает текущий
поток, пока критическая секция не освободится .
В конце критической секции вызывается подпрограмма
procedure LeaveCriticalSection (sect:TRTLCriticalSection);
которая делает пометку в записи , что критическая секция свободна, и дру -
гой поток в соответствии с приоритетом получает квант времени и входит в кри-
тическую секцию .
Предварительно перед использованием необходимо проинициализировать
запись sect: TRTLCriticalSection с помощью процедуры
procedure InitializeCriticalSection(Sect);
а при завершении использования – удалить :
procedure DeleteCriticalSection(Sect1);
В рассматриваемом ниже примере первая операция выполняется в обра-
ботчике события создания формы OnCreate, а вторая – в обработчике события
удаления формы из памяти OnDestroy.
4. С ин хро н изация п о то ко в К ак уж е уп оминалось, п ри доступ е п отоков к об щ им ресурсам (г лоб аль- ны м данны м, одному итому ж е ф айлу, DLL, коммуникационному п орту ит.п .) возникаю т коллизии. П редотвратить коллизии мож но с п омощ ью различны х средств синхронизации. Ч ащ е вс ег о для этой цели ис п ользую тся: кр и т и чески е секци и , и склю ча ю щи е сем а ф ор ы (м ью т ексы), обычн ые сем а ф ор ы, событ и я. В се уп омянуты емеханизмы основаны наб локировкедоступ ак ресурсу, п окаэтотре- сурсзаняткаким-либ о п отоком. Рассмотрим б олее п одроб но механизм критической секции, ог раничив- ш ись ег о реализацией наб азеф ункций API Win32 (как об ы чно, в Delphi имею тся аналог ичны е классы -надстройки). У часток кода, содерж ащ ий п отенциально оп асны е об ращ ения к ресурсу, п омечается как « критическая с екция». П еред вхо- дом в критическую с екцию п роверяется г лоб альная зап ись тип аTRTLCriticalSec- tion (структуру зап исисм. в ф айле ..\borland\delphi4\source\rtl\win\windows.pas), в которой отмечено, вы п олняется ликритическая секция в данны й моментвремени каким-либ о друг им п отоком. Е слисекция незанята, п оток доп ускается к раб оте. В началекритической секциинеоб ходимо вы звать п одп рог рамму API procedure EnterCriticalSection (sect:TRTLCriticalSection); которая п роверяетсостояниезап исиsect: TRTLCriticalSection и, еслив за- п исисекция п омеченакак занятая друг им п отоком, п риостанавливаеттекущ ий п оток, п окакритическая секция неосвоб одится. В концекритичес кой секциивы зы вается п одп рог рамма procedure LeaveCriticalSection (sect:TRTLCriticalSection); которая делаетп ометку в зап иси, что критическая секция своб одна, идру- г ой п оток в соответствиисп риоритетом п олучаетквантвремениивходитв кри- тическую секцию . П редварительно п еред исп ользованием необ ходимо п роинициализировать зап ись sect: TRTLCriticalSection сп омощ ью п роцедуры procedure InitializeCriticalSection(Sect); ап ризаверш енииисп ользования – удалить: procedure DeleteCriticalSection(Sect1); В рассматриваемом ниж еп римереп ервая оп ерация вы п олняется в об ра- б отчикесоб ы тия создания ф ормы OnCreate, авторая – в об раб отчикесоб ы тия удаления ф ормы изп амятиOnDestroy. 12
Страницы
- « первая
- ‹ предыдущая
- …
- 10
- 11
- 12
- 13
- 14
- …
- следующая ›
- последняя »