Разница между функцией WaitFor для TMutex delphi и аналогом в Win32 API - PullRequest
2 голосов
/ 28 мая 2010

Документация delphi гласит, что функция WaitFor для TMutex и других объектов синхронизации синхронизирует ожидание, пока не будет передан дескриптор объекта. Но эта функция также гарантирует владение объектом для вызывающей стороны?

Ответы [ 2 ]

3 голосов
/ 28 мая 2010

Да, вызывающий поток TMutex владеет мьютексом; класс - это просто оболочка для объекта мьютекса ОС. Убедитесь сами, проверив SyncObjs.pas .

То же самое не относится к другим объектам синхронизации, таким как TCriticalSection. Любой поток может вызвать метод Release для такого объекта, а не только поток, вызвавший Acquire.

2 голосов
/ 28 мая 2010

TMutex.Acquire - это обертка вокруг THandleObjects.WaitFor, которая будет вызывать WaitForSingleObject ИЛИ CoWaitForMultipleHandles в зависимости от аргумента UseCOMWait.
Это может быть очень важно, если вы используете COM-объекты STA в своем приложении (вы можете сделать это, не зная, например, dbGO / ADO - это COM), и вы не хотите тупиковать.
Все еще опасно вводить длительное / бесконечное ожидание в главном потоке, потому что единственный метод, который правильно обрабатывает вызовы, сделанные с помощью TThread.Synchronize, это TThread.WaitFor, и вы можете заблокировать (или заблокировать) свои рабочие потоки, если вы используете Объекты SyncObjs или функции ожидания WinAPI.
В коммерческих проектах я использую пользовательский метод ожидания, основанный на идеях обоих THandleObjects.WaitFor И TThread.WaitFor с необязательным ожидающим оповещением (хорошо для асинхронного ввода-вывода, но незаменимый для возможности прервать длинные ожидания).

Редактировать: дальнейшие разъяснения относительно COM / OLE:

В модели COM / OLE (например, ADO) могут использоваться разные модели резьбы: STA (однопоточная) и MTA (многопоточная или свободная).
По определению основной поток графического интерфейса инициализируется как STA, что означает, что COM-объекты могут использовать оконные сообщения для своего асинхронного обмена сообщениями (особенно при вызове из других потоков для безопасной синхронизации). AFAIK, они также могут использовать процедуры APC.
Существует веская причина существования функции CoWaitForMultipleHandles - см. Ее использование в SyncObjs.pas THandleObject.WaitFor - в зависимости от модели потоков, она может обрабатывать внутренние COM-сообщения, блокируя дескриптор ожидания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...