![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| unReg |
|
|||
|
Unregistered |
Здравствуйте. Нашел в вашем форуме топик о мьютексах, но он оказался не совсем про мьютексы. Непонятно действие некоторых функций (в аглицком не силен). Мне нужно было синхронизировать доступ к файлу со стороны разных приложений. Одно приложение (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 |
|
||||||
|
Unregistered |
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 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 30.9.2003 Где: Saint-Petersburg Репутация: 5 Всего: 4 |
Для начала вот это место:
3 begin'a & 2 end'a - это нормально? --------------------
/DVA |
|||
|
||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Попробуй в WaitForSingleObject вместо 0 поставить INFINITE, а так всё правильно, и в первом варианте второго кода нужно делать CloseHandle
-------------------- С уважением, г-н Посол. |
|||
|
||||
| Unregistered |
|
|||
|
Unregistered |
Dmitry V.Abramov нашел к чему прицепиться
p0s0l Спасибо, но флаг infinite на сколько я понял заставляет ждать до тех пор пока не получит сигнала? |
|||
|
||||
| Ars |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 325 Регистрация: 28.8.2003 Где: Московская обл. Репутация: нет Всего: 2 |
Проблема в том, что при каждом вхождении ты получаешь новый дескриптор мьютекса и нигде его не освобождаешь. Поэтому у тебя всегда новое значение дескриптора и растет счетчик дескрипторов. Я не понимаю, зачем вообще каждый раз получать дескриптор. Достаточно получить его однажды в начале работы приложения и хранить в данных TfrmMain или в глобальной переменной. Функция OpenMutex, действительно, получает хэндл на существующий мьютекс, а если он не существует, то обламывается, в отличии от CreateMutex, которая или создает новый или открывает существующий (что именно, можно проверить последующим вызовом GetLastError). Tем самым устраняется необходимость последовательных вызовов OpenMutex, CreateMutex и проверок хэндлов для получения мьютекса. Кстати, у тебя нигде нет проверки на валидность хэндла...
-------------------- Есть многое на свете, друг Горацио, С чем очень долго можно прое..! |
||||
|
|||||
| Unregistered |
|
|||
|
Unregistered |
Спасибо. Тут чего-то действительно фигню спорол (каждый раз открывыл мьютекс). Это явно ни к чему.
В любом случае, господа, вы мне очень помогли. Еще раз - спасибо. |
|||
|
||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |