| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Mutex |
| Автор: unReg 3.12.2003, 02:29 |
| Здравствуйте. Нашел в вашем форуме топик о мьютексах, но он оказался не совсем про мьютексы. Непонятно действие некоторых функций (в аглицком не силен). Мне нужно было синхронизировать доступ к файлу со стороны разных приложений. Одно приложение (1) создает и постоянно обновляет файл, а другое(ие) (2) просто читает его содержимое. (1) создает мьютекс в момент своего создания, а (2) берет хендл созданного мьютекса с помощью OpenMutex. Работа с файлом начинается после WaitForSingleObject (стандартный вариант). По окончании работы с файлом делаю ReleaseMutex и в (1) и в (2). CloseHandle делаю по Destroy (1). И вот что получается: 1: работа с файлом синхронизируется. (это хорошо) 2: как уже говорилось-счетчик дескрипторов неуклонно растет пока работает (2)! (это плохо) 3: если я делаю в (2) CloseHandle после работы с файлом, то (1) затыкается на WaitForSingleObject. (а это вообще противоречит 2-му пункту). Проблему 2 и 3 сейчас решаю так: при каждом обращении к файлу из (2), вместо OpenMutex делаю CreateMutex, потом WaitForSingleObject, потом ReleaseMutex и CloseHandle. Нафиг тогда OpenMutex? если как написано в справке The OpenMutex function returns a handle of an existing named mutex object. Или я че-то неправильно понимаю? |
| Автор: unReg 4.12.2003, 03:08 | ||||||
| OK. Наверное без кода никто не ответит. Каюсь. Код потока (1) который создает мьютекс (каждый поток работает со своим файлом и своим MutexName):
Теперь код приложения которое читает файл (2) первый вариант:
Вот при таком раскладе растет счетчик дескрипторов. Если после ReleaseMutex(hMutex); написать CloseHandle(hMutex), то (1) затыкается на waitforsingleobject (таймаут); А если код (2) написать вот так (второй вариант):
тогда счетчик не увеличивается, и все вроде бы нормально, но! Обнаружилась еще одна странность. Я попробовал вывести значение hMutex в Caption формы (caption:=inttostr(hMutex)) и в первом варианте кода (2) выходили разные(!) значения при каждой отработке процедуры, а во втором варианте значения одинаковые(!). Мало того, во втором варианте я откомпилил приложение (2) в нескольких вариантах (каждому потоку (1) соответствовал вариант приложения (2), естественно имена мьютексов и файлов различались в каждом потоке) и опять получил одинаковые значения hMutex во всех(!) запущенных приложениях (2). Вопрос, собственно, вот в чем: почему не работает первый вариант кода и че за ерунда с хендлами? |
| Автор: Dmitry V.Abramov 4.12.2003, 17:46 | ||
Для начала вот это место:
3 begin'a & 2 end'a - это нормально? |
| Автор: p0s0l 4.12.2003, 21:59 |
| Попробуй в WaitForSingleObject вместо 0 поставить INFINITE, а так всё правильно, и в первом варианте второго кода нужно делать CloseHandle |
| Автор: Unregistered 5.12.2003, 02:09 |
| Dmitry V.Abramov нашел к чему прицепиться p0s0l Спасибо, но флаг infinite на сколько я понял заставляет ждать до тех пор пока не получит сигнала? |
| Автор: Ars 5.12.2003, 18:35 | ||||
Проблема в том, что при каждом вхождении ты получаешь новый дескриптор мьютекса и нигде его не освобождаешь. Поэтому у тебя всегда новое значение дескриптора и растет счетчик дескрипторов. Я не понимаю, зачем вообще каждый раз получать дескриптор. Достаточно получить его однажды в начале работы приложения и хранить в данных TfrmMain или в глобальной переменной. Функция OpenMutex, действительно, получает хэндл на существующий мьютекс, а если он не существует, то обламывается, в отличии от CreateMutex, которая или создает новый или открывает существующий (что именно, можно проверить последующим вызовом GetLastError). Tем самым устраняется необходимость последовательных вызовов OpenMutex, CreateMutex и проверок хэндлов для получения мьютекса. Кстати, у тебя нигде нет проверки на валидность хэндла...
|
| Автор: Unregistered 8.12.2003, 01:55 |
| Спасибо. Тут чего-то действительно фигню спорол (каждый раз открывыл мьютекс). Это явно ни к чему. В любом случае, господа, вы мне очень помогли. Еще раз - спасибо. |