Разница между функцией WaitFor для TMutex delphi и аналогом в Win32 API
Документация delphi гласит, что функция WaitFor для TMutex и других объектов синхронизации синхронизирует ожидание, пока дескриптор объекта не будет сигнализирован. Но эта функция также гарантирует право собственности на объект для вызывающей стороны?
2 ответа
Да, вызывающая нить TMutex
владеет мьютексом; класс - это просто оболочка для объекта мьютекса ОС. Убедитесь сами, проверив SyncObjs.pas.
То же самое не верно для других объектов синхронизации, таких как TCriticalSection
, Любая нить моя называется Release
метод для такого объекта, а не только поток, который вызвал Acquire
,
TMutex.Acquire
это обертка вокруг THandleObjects.WaitFor
, который позвонит WaitForSingleObject
ИЛИ ЖЕ CoWaitForMultipleHandles
в зависимости от UseCOMWait
аргумент конструктора.
Это может быть очень важно, если вы используете STA COM-объекты в своем приложении (вы можете сделать это, не зная, например, dbGO/ADO - это COM), и вы не хотите тупиковать.
Все еще опасно вводить долгое / бесконечное ожидание в основной поток, потому что единственный метод, который правильно обрабатывает вызовы, сделанные через TThread.Synchronize
является TThread.WaitFor
и вы можете заблокировать (или заблокировать) рабочие потоки, если используете объекты SyncObjs или функции ожидания WinAPI.
В коммерческих проектах я использую собственный метод ожидания, основанный на идеях обоих THandleObjects.WaitFor
А ТАКЖЕ TThread.WaitFor
с необязательным ожидаемым оповещением (хорошо для асинхронного ввода-вывода, но незаменимо для возможности прервать длительное ожидание).
Изменить: дальнейшие разъяснения относительно COM/OLE:
Модель COM / OLE (например, ADO) может использовать различные модели резьбы: STA (однопоточная) и MTA (многопоточная или свободная).
По определению основной поток GUI инициализируется как STA, что означает, что COM-объекты могут использовать оконные сообщения для своего асинхронного обмена сообщениями (особенно при вызове из других потоков, для безопасной синхронизации). AFAIK, они также могут использовать процедуры APC.
Есть веская причина для CoWaitForMultipleHandles
функция существует - см. ее использование в SyncObjs.pas THandleObject.WaitFor
- в зависимости от модели потоков, он может обрабатывать внутренние COM-сообщения, в то же время блокируя дескриптор ожидания.