![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как дождаться уничтожения MUTEXa [D7, WinXP]
Stanislav © (2005-04-21 12:10:00)Делаю так:
По таймеру выполняю сл. процедуру. см. ниже.
Но если Мютекса небыло все ок.
А если был, то после закрытия создавшего его приложения все равно не выполняется условие.
procedure TForm1.Timer1Timer(Sender: TObject);
begin
HMutex:=CREATEMUTEX (nil,false,'SS_Mutex_ForUpdate');
if (getLastError<>ERROR_ALREADY_EXISTS) then
begin
...
...
end;
end;
Eraser (2005-04-21 14:33:00) [1]alpet ©
будет правильней - WaitForSingleObject применительно к дескриптору процесса.
Согласен. Но без мьютексов не обойтись... и та и другая программа должны быть запущены в 1 экземпляре.
alpet (2005-04-21 14:28:00) [2]В случае работы с памятью ты на 110% прав, НЕОБХОДИМО освобождать память самому. Но в данном случае конечно можно закрывать дескриптор где-нибудь в OnDestroy главной формы, но это опять таки не очень правильно... вдруг программа подвиснит после OnDestroy...
Я такого поворота событий не учел. Но тут опять же специализованный прямой подход будет правильней - WaitForSingleObject применительно к дескриптору процесса. Не нужно будет создавать какие либо дополнительные ГОС, хотя сам дескриптор извлекать будет сложнее.
А обновление файла DLL можно совершить проверяя его на доступность OpenFile (..., OF_SHARE_EXCLUSIVE).
Stanislav (2005-04-21 14:25:00) [3]Понятно, спасибо.
Eraser (2005-04-21 14:13:00) [4]Stanislav ©
Каждый модуль на закрытие вызывает программу обновления dll (вторую).
Тогда CloseHandle должен выполнятся ДО вызова другой программы... а вообще логика не верная.
Я бы посоветовал использовать ф-ю WaitForSingleObject. Внутри длл просле успешного создания мьютекса заходить в него (второй параметр = true), а после запуска 2 программы попробовать открыть мьютекс и если он занят- ждать WaitForSingleObject(можно 30 секунд).
Stanislav (2005-04-21 14:02:00) [5]Суть программы:
Есть несколько модулей, которые работают с одной Dll, каждый модуль может вызвать другой после чего сам закрывается.
Нужно по закрытию последнего модуля обновить dll с сервера.
Для чего и служит вторая программа.
Мютексы создаются в процедуре dll - Start, которая вызывается каждым модулем при старте.
Каждый модуль на закрытие вызывает программу обновления dll (вторую). Она должна проверить нет ли мьютекса и если нет, то выполнится, а если есть, то ждать пока его не станет, а потом выполнить обновления. Либо закрыться если мютекс существует в течении 30 сек. (этого я еще не делал)
Stanislav (2005-04-21 13:55:00) [6]Первая очень большая, но все что касается Мютекса вот:
Инициализация:
HUMutex:=CreateMutex (NIL,false,'SS_Mutex_ForUpdate');
Ну, и вконце CloseHandle (HUMutex), это я дописал потом.
А вторая вот
procedure TForm1.Timer1Timer(Sender: TObject);
Var T:Array [1..2] of string;
HMutex:Integer;
begin
HMutex:=OPenmutex(MUTEX_ALL_ACCESS ,false,'SS_Mutex_ForUpdate');
//if (getLastError<>ERROR_ALREADY_EXISTS) then
//HMutex:=FindWindow ('TFmTest','fmTest');
if HMutex=0 then
begin
if LoadText (t,'fl.txt') then //чтение из файла путей
UpdateFiles (t[1],t[2]); // обновление файлов
Application.Terminate;
end;
end;
Eraser (2005-04-21 13:45:00) [7]Stanislav ©
НОРМАЛЬНО приведи:
1. Код первой программы (хотя бы проверку и инициализацию)
2. Код второй программы.
alpet ©
В случае работы с памятью ты на 110% прав, НЕОБХОДИМО освобождать память самому. Но в данном случае конечно можно закрывать дескриптор где-нибудь в OnDestroy главной формы, но это опять таки не очень правильно... вдруг программа подвиснит после OnDestroy...
Stanislav (2005-04-21 13:41:00) [8]Eraser © (21.04.05 13:34) [13]
Когда первая программа, создавшая мютекс закрылась, то вторая которая проверяет наличие мютекса не определяет что его нет. Хотя если запустить вторую программу без первой, то она определяет что мютекса нет.
alpet © (21.04.05 13:27) [10]
CloseHandle делаю.
alpet (2005-04-21 13:39:00) [9]> Зачем закрывать мьютекс?
Ну да, забыл - все что не освобождаешь сам - освободит система. Я просто к таким правилам стараюсь не привыкать.
alpet (2005-04-21 13:39:00) [10]> Зачем закрывать мьютекс?
Ну да, забыл - все что не освобождаешь сам - освободит система. Я просто к таким правилам стараюсь не привыкать.
Eraser (2005-04-21 13:34:00) [11]Stanislav ©
Я в принципе решил проблему, ищу окно, все работает
До поры до времени....
почему не получается с Mutex'ом
Так ЧТО конкретно не получается?
Eraser (2005-04-21 13:32:00) [12]alpet ©
Ядру известно, сколько процессов использует конкретный объект ядра, посколь ку в каждом объекте есть счетчик числа его пользователей. Этот счетчик — один из элементов данных, общих для всех типов объектов ядра. В момент создания объекта счетчику присваивается 1. Когда к существующему объекту ядра обращается другой процесс, счетчик увеличивается на 1. А когда какой-то процесс завершается, счетчики всех используемых им объектов ядра автоматически уменьшаются на 1. Как только счетчик какого-либо объекта обнуляется, ядро уничтожает этот объект.
Рихтер.
Зачем закрывать мьютекс?
Stanislav (2005-04-21 13:29:00) [13]Eraser © (21.04.05 13:21) [9]
Таймер остался, просто я кусок кода достал.
А строкой хочу проверить если 0 значит Mutexа нет.
Я в принципе решил проблему, ищу окно, все работает, но хотелось бы узнать почему не получается с Mutex'ом.
alpet (2005-04-21 13:27:00) [14]У тебя в первой программе сам Mutex закрывается (CloseHandle)?
Вообще для этой задачи лучше использовать WaitForSingleObject (hProcess, 100) <> WAIT_TIMEOUT в таймере
Eraser (2005-04-21 13:21:00) [15]Stanislav ©
А куда таймер то делся?
Что ты ХОЧЕШЬ проверить данной строкой
if HMutex=0 then
Stanislav (2005-04-21 13:15:00) [16]Сделал OpenMutex все равно не работает.
HMutex:=OPenmutex(MUTEX_ALL_ACCESS ,false,'SS_Mutex_ForUpdate');
ShowMessage (IntToStr (HMutex));
if HMutex=0 then
begin
...
Application.Terminate;
end;
Eraser (2005-04-21 12:32:00) [17]Eraser ©
Не так выразился! Создаёт мьютекс при проверке программа, которая проверяет. Короче при ТАКОЙ проверке этот самый мьютекс и создаётся.
Eraser (2005-04-21 12:30:00) [18]Stanislav ©
Так та другая программа (которая выполняет определённые действия) если нет мьютекса, создаёт его и потом проверяет сама себя.
Для этих целей тебе нужна ф-я OpenMutex.
Stanislav (2005-04-21 12:28:00) [19]Eraser © (21.04.05 12:24) [3]
if (getLastError<>ERROR_ALREADY_EXISTS) then
begin
...
...
Application.terminate;
end;
Stanislav (2005-04-21 12:26:00) [20]Eraser © (21.04.05 12:17) [1]
У меня немного не так
Запускается одна программа и создает Mutex,
Потом запускается другая, которая должна проверять если есть Mutex, то ничего не делать, а как Mutex пропал, то выполнить определенные действия и закрыться.