Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Мьютексы и Win API 
:(
    Опции темы
IRQ
Дата 1.6.2006, 01:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 7.5.2006

Репутация: нет
Всего: нет



Хочу создать программу с мьютексами. Использую функции API для создания мьютексов. Но почему-то не работает прога. Вот что пытаюсь сделать:

Код

Mutexes[0]:=CreateMutex(nil,true,'qq');
self.Caption:=IntToStr(Mutexes[0]);
Mutexes[0]:=OpenMutex($00100000,false,'qq');
self.Caption:=self.Caption+IntToStr(Mutexes[0]);


$00100000-это вместо слова Synchronize. А то конфликтует с методом одноимённым. Вопрос: Почему возвращаемые значения различаются? Или я неправильно понял работу функций. Как я понимаю, CreateMutex создаёт мьютекс. Далее, если мы хотим его использовать, то получаем его Handle по имени. С помощью OpenMutex. Но почему в этом примере раличаются возвращаемые значения. Причём на 4. И вообще зачем использовать OpenMutex? Можно ли при написании программы с синхронизацией потоков не использовать OpenMutex? 
PM MAIL   Вверх
Nickel
Дата 1.6.2006, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 7.2.2006

Репутация: 2
Всего: 4



CreateMutex уже возвращает хендл мьютекса, причём с доступом MUTEX_ALL_ACCESS. OpenMutex открывает ещё один хендл. Т.е. при синхронизации 2 процессов, например, 1 процесс должен создать мьютекс, а второй его открывать и в зависимости от результата (получилось или не получилось), что-то делать. 
PM   Вверх
IRQ
Дата 1.6.2006, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 7.5.2006

Репутация: нет
Всего: нет



То есть получается надо писать
Код

if OpenMutex($00100000,false,'qq')=0 then
  Mutexes[0]:=CreateMutex(nil,true,'qq');

Но поскольку у меня не было до этого мьютексов с именами, которые я задаю, получается, что я могу просто написать
Код

Mutexes[0]:=CreateMutex(nil,true,'qq');

То есть получается, что мне не надо вообще использовать функцию OpenMutex. Я видел такое при запрете запуска второго экземпляра приложения. Но тогда возникает вопрос, как это связано? Получается, что у каждого приложения уже есть созданный мьютекс? И потом в справке по MS SDK я не увидел строчки, в которой говорилось бы, что OpenMutex создаёт ещё один мьютекс. Там написано, что она открывает уже созданный мьютекс. Значит по мсыслу мой код должен был работать. И отличаются ли чем-нибудь флаги MUTEX_ALL_ACCESS от SYNCHRONIZE? Опять же в справке я не нашёл ничё прямо такого отличающегося. В обоих случаях написано, что Handle мьютекса может использоваться в функцих WaitFor и других. По все видимости они различаются, еси задан флаг атрибутов безопасности.  

Это сообщение отредактировал(а) IRQ - 1.6.2006, 09:59
PM MAIL   Вверх
Nickel
Дата 1.6.2006, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 7.2.2006

Репутация: 2
Всего: 4



Мьютекс - он один на всех. CreateMutex создаёт новый мьютекс, если мьютекса с таким именем ещё нет, иначе открывает мьютекс и возвращает его хендл. OpenMutex только открывает мьютекс, возвращая его хендл, а если он не существует функция возвращает 0. У одного и того же процессов может быть много хендлов одного мьютекса, поэтому когда ты сначла создаешь мьютекс при помощи CreateMutex, а потом его ещё и открываешь OpenMutex, то получаешь два разных хендла одного и того же мьютекса.  
PM   Вверх
IRQ
Дата 1.6.2006, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 7.5.2006

Репутация: нет
Всего: нет



Теперь понятно. Я-то думал, зачем для одного мьютекса разные хэндлы. Хотя так и не могу понять зачем smile Создали-есть. Так же как и указатель скажем. Зачем-то надо для одного мьютекса несколько разных хэндлов делать. 
PM MAIL   Вверх
maxim1000
Дата 1.6.2006, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: нет
Всего: 110



Цитата(IRQ @  1.6.2006,  13:03 Найти цитируемый пост)
Зачем-то надо для одного мьютекса несколько разных хэндлов делать.

например, чтобы другой процесс получил handle мьютекса сделанного первым 


--------------------
qqq
PM WWW   Вверх
IRQ
Дата 1.6.2006, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 7.5.2006

Репутация: нет
Всего: нет



А как работать с WaitFOrMultipleObjects. Туда надо передавать адрес массива. А у меня оба потока захватывают ресурсы и в итоге прога виснет. Я хочу сделать один масиив с уже созданными мьютексами. А потом в потом в поток передавать массив с мьютексами, которые он должен захватить. То есть Что-то типа того:
Код

//Создали мьютексы
for i:=0 to 3 do
  Mutexes[i]:=CreateMutex(nil,false,PChar('Resource'+IntToStr(i+1)));
//Заполняем массив необходимых мьютекосв (array of THandle)
SetLength(Handles,2);
Handles[0]:=Mutexes[0];
Handles[1]:=Mutexes[1];
t=MyThread.Create(false,Handles);
//Я передаю массив и присваиваю его свойству потока в конструкотре потока
...
self.FHandles:=Hadnles;
//И далее в методе Execute пытаюсь захватить все мьютексы
if WaitForMultipleObjects(2,@self.FHandles,false,5000)=WAIT_TIMEOUT then
  ....

Здесь я предполагаю, что поток захватит нужные ресурсы. Но когда я создаю ещё один поток, он тоже захватывает те же ресурсы и прога виснет. почему? Вроде THandle-просто число. И Если мы задаём просто список чисел, то поток должен их захватить и не дать другому потоку этого сделать. Но получается, что 2й поток тоже захватывает. и всё виснет. Как можно выйти из такого положения? 
PM MAIL   Вверх
Nickel
Дата 1.6.2006, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 7.2.2006

Репутация: 2
Всего: 4



Немного не понимаю, что ты хочешь сделать. Вот пример: допустим один поток должен дождаться когда второй поток выполнит некоторую работу и тоже выполнить некоторую работу =) Второй поток создаёт некоторый мьютекс, т.е сигнализирует что начал свою работу. В это время первый поток открывает мьютекс и пытается его захватить (т.е. делает WaitForSingleObject). Второй поток, как только произведёт некоторые действия, освобождает мьютекс (ReleaseMutex), и в этот момент первому потоку удаётся захвтить этот мьютекс.
Код

procedure potok1;
var h : Cardinal;
begin
 repeat
  h:=OpenMutex(MUTEX_ALL_ACCESS, false, 'aaa');
 until h<>0;
 WaitForSingleObject(h, INFINITE);
 MessageBox(0,'Âòîðîé ïîòîê îòðàáîòàë','Ïåðâûé ïîòîê',0);
end;

procedure potok2;
var h : CArdinal;
begin
 h:=CreateMutex(nil, true, 'aaa');
 MessageBox(0, 'Âòîðîé ïîòîê íà÷àë ðàáîòó', 'Âòîðîé ïîòîê', 0);
 ReleaseMutex(h);
 MessageBox(0, 'Âòîðîé ïîòîê íà÷àë ðàáîòó, íå òðåáóþùóþ ñèíõðîíèçàöèè', 'Âòîðîé ïîòîê', 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var TID : Cardinal;
begin
CreateThread(nil, 0, @potok1, nil, 0, TID);
CreateThread(nil, 0, @potok2, nil, 0, TID);
end;

end.
 
PM   Вверх
IRQ
Дата 1.6.2006, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 7.5.2006

Репутация: нет
Всего: нет



Ну так я могу синхронизировать потоки smile Это у меня даже получалось. Но делао в том, что задача стоит так, как нарисовано в прикреплённом файле. Я создал 4 мьютекса. На форме 4 прямоугольника (ресурсы и 4 круга разного цвета (потоки). И хочу, чтобы владение ресурсом отображалось миганием ресурсов. Я просто ничего лучше не нашёл, что можно в Execute написать. В execute написано следующее:
Код

while not self.Terminated do
  if WaitForMultipleObjects(2,@self.FHandles,true,5000)=WAIT_TIMEOUT then
    begin
    self.FSuccess:=false;
    self.Terminate;
    Exit;
    end
  else
    begin
    self.FSuccess:=true;
    self.Synchronize(self.UpdateShapes);
    end;

В массиве-два мьютекса. Поток изх захватывает. В методе UpdateShapes мигают фигуры  на главной форме. С помощью таймера, который встроен в мой поток. Но дело в том, что после запуска второго потока хотя бы, прога виснет. Видимо, из-за постоянного обновления фигур виснет сам VCL-поток. Я не могу придумать, как это всё дело отобразить. Что написать в Execute. Если туда написать увеличение счётчика или перерисовка, то виснет всё. А что ещё можно-не знаю. Как мне отобразить наглядно, что какой-то поток чем-то владеет. И опять же при захвате всё начинает виснуть. Важныйв вопрос-что писать в Execute. Куда писать WaitForMultipleObjects и прочие функции. Как их грамотно расставить? 

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  SPO.JPG 14,39 Kb
PM MAIL   Вверх
IRQ
Дата 3.6.2006, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 7.5.2006

Репутация: нет
Всего: нет



Снова появился вопрос. Программу я вроде сделал. Но есть проблема. Я захватываю потокм какой-то ресурс (по нажатию на кнопку). Затем мне необходимо к уже захваченным ресурсам добавить ещё ресурсы. Это тоже делается кнопкой.  Дело в том, что если ресур свободен, то всё нормально. Всё захватывается. Но если ресур занят, то поток прожидает 5 секунд (таймаут) и только потом выдаёт сообщение. Так вот главная проблема в том, что поскольку попытка захвата делается из главного потока, главный поток тоже простаивает, пока поток пытается захватить ресурсы. И получается, что если поток не может захватить ресурс, то на это время (5 секунд) главный поток подвисает и программа не отвечает. Можно ли это как-нибдуь обойти? Я не вижу никаких способов, потому как вызов захвата всё равно происходит из главного потока. И он всё равно должен ждать выхода из процедуры. 
PM MAIL   Вверх
Демо
Дата 5.6.2006, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 6
Всего: 50



Цитата(IRQ @  3.6.2006,  17:23 Найти цитируемый пост)
 потому как вызов захвата всё равно происходит из главного потока.


Почему? 


--------------------
    
PM MAIL ICQ Skype   Вверх
IRQ
Дата 6.6.2006, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 7.5.2006

Репутация: нет
Всего: нет



Ну как почему. Ведь я нажимаю кнопку. И обработчик ждёт возварата из процедуры. В которй как раз и происходит попытка захвата. И пока 5 секунд не пройдут, возврата не произойдёт. А значит кнопка так и не будет отжата. И приложение не убдет отвечать на запрсы новые. только потом. После 5 секнуд. 
PM MAIL   Вверх
Демо
Дата 7.6.2006, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 6
Всего: 50



IRQ
Так работай с ресурсами из дополнительных потоков. 


--------------------
    
PM MAIL ICQ Skype   Вверх
IRQ
Дата 8.6.2006, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 7.5.2006

Репутация: нет
Всего: нет



Но ведь попытка захвата ресурсов делается всё равно по нажатию кнопки. И всё равно этот путь начинается отсюда. И обработчик должен ждать возвращения из процедуры захвата. Я же не могу просто так когду вздумается захватывать ресурсы. А по нажатию на кнопку. 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1570 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.