Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Delphi: WinAPI и системное программирование > Мьютексы и Win API |
Автор: IRQ 1.6.2006, 01:10 | ||
Хочу создать программу с мьютексами. Использую функции API для создания мьютексов. Но почему-то не работает прога. Вот что пытаюсь сделать:
$00100000-это вместо слова Synchronize. А то конфликтует с методом одноимённым. Вопрос: Почему возвращаемые значения различаются? Или я неправильно понял работу функций. Как я понимаю, CreateMutex создаёт мьютекс. Далее, если мы хотим его использовать, то получаем его Handle по имени. С помощью OpenMutex. Но почему в этом примере раличаются возвращаемые значения. Причём на 4. И вообще зачем использовать OpenMutex? Можно ли при написании программы с синхронизацией потоков не использовать OpenMutex? |
Автор: Nickel 1.6.2006, 08:35 |
CreateMutex уже возвращает хендл мьютекса, причём с доступом MUTEX_ALL_ACCESS. OpenMutex открывает ещё один хендл. Т.е. при синхронизации 2 процессов, например, 1 процесс должен создать мьютекс, а второй его открывать и в зависимости от результата (получилось или не получилось), что-то делать. |
Автор: IRQ 1.6.2006, 09:51 | ||||
То есть получается надо писать
Но поскольку у меня не было до этого мьютексов с именами, которые я задаю, получается, что я могу просто написать
То есть получается, что мне не надо вообще использовать функцию OpenMutex. Я видел такое при запрете запуска второго экземпляра приложения. Но тогда возникает вопрос, как это связано? Получается, что у каждого приложения уже есть созданный мьютекс? И потом в справке по MS SDK я не увидел строчки, в которой говорилось бы, что OpenMutex создаёт ещё один мьютекс. Там написано, что она открывает уже созданный мьютекс. Значит по мсыслу мой код должен был работать. И отличаются ли чем-нибудь флаги MUTEX_ALL_ACCESS от SYNCHRONIZE? Опять же в справке я не нашёл ничё прямо такого отличающегося. В обоих случаях написано, что Handle мьютекса может использоваться в функцих WaitFor и других. По все видимости они различаются, еси задан флаг атрибутов безопасности. |
Автор: Nickel 1.6.2006, 10:54 |
Мьютекс - он один на всех. CreateMutex создаёт новый мьютекс, если мьютекса с таким именем ещё нет, иначе открывает мьютекс и возвращает его хендл. OpenMutex только открывает мьютекс, возвращая его хендл, а если он не существует функция возвращает 0. У одного и того же процессов может быть много хендлов одного мьютекса, поэтому когда ты сначла создаешь мьютекс при помощи CreateMutex, а потом его ещё и открываешь OpenMutex, то получаешь два разных хендла одного и того же мьютекса. |
Автор: IRQ 1.6.2006, 14:03 |
Теперь понятно. Я-то думал, зачем для одного мьютекса разные хэндлы. Хотя так и не могу понять зачем ![]() |
Автор: maxim1000 1.6.2006, 14:06 |
например, чтобы другой процесс получил handle мьютекса сделанного первым |
Автор: IRQ 1.6.2006, 14:37 | ||
А как работать с WaitFOrMultipleObjects. Туда надо передавать адрес массива. А у меня оба потока захватывают ресурсы и в итоге прога виснет. Я хочу сделать один масиив с уже созданными мьютексами. А потом в потом в поток передавать массив с мьютексами, которые он должен захватить. То есть Что-то типа того:
Здесь я предполагаю, что поток захватит нужные ресурсы. Но когда я создаю ещё один поток, он тоже захватывает те же ресурсы и прога виснет. почему? Вроде THandle-просто число. И Если мы задаём просто список чисел, то поток должен их захватить и не дать другому потоку этого сделать. Но получается, что 2й поток тоже захватывает. и всё виснет. Как можно выйти из такого положения? |
Автор: Nickel 1.6.2006, 18:38 | ||
Немного не понимаю, что ты хочешь сделать. Вот пример: допустим один поток должен дождаться когда второй поток выполнит некоторую работу и тоже выполнить некоторую работу =) Второй поток создаёт некоторый мьютекс, т.е сигнализирует что начал свою работу. В это время первый поток открывает мьютекс и пытается его захватить (т.е. делает WaitForSingleObject). Второй поток, как только произведёт некоторые действия, освобождает мьютекс (ReleaseMutex), и в этот момент первому потоку удаётся захвтить этот мьютекс.
|
Автор: IRQ 1.6.2006, 18:52 | ||
Ну так я могу синхронизировать потоки ![]()
В массиве-два мьютекса. Поток изх захватывает. В методе UpdateShapes мигают фигуры на главной форме. С помощью таймера, который встроен в мой поток. Но дело в том, что после запуска второго потока хотя бы, прога виснет. Видимо, из-за постоянного обновления фигур виснет сам VCL-поток. Я не могу придумать, как это всё дело отобразить. Что написать в Execute. Если туда написать увеличение счётчика или перерисовка, то виснет всё. А что ещё можно-не знаю. Как мне отобразить наглядно, что какой-то поток чем-то владеет. И опять же при захвате всё начинает виснуть. Важныйв вопрос-что писать в Execute. Куда писать WaitForMultipleObjects и прочие функции. Как их грамотно расставить? |
Автор: IRQ 3.6.2006, 17:23 |
Снова появился вопрос. Программу я вроде сделал. Но есть проблема. Я захватываю потокм какой-то ресурс (по нажатию на кнопку). Затем мне необходимо к уже захваченным ресурсам добавить ещё ресурсы. Это тоже делается кнопкой. Дело в том, что если ресур свободен, то всё нормально. Всё захватывается. Но если ресур занят, то поток прожидает 5 секунд (таймаут) и только потом выдаёт сообщение. Так вот главная проблема в том, что поскольку попытка захвата делается из главного потока, главный поток тоже простаивает, пока поток пытается захватить ресурсы. И получается, что если поток не может захватить ресурс, то на это время (5 секунд) главный поток подвисает и программа не отвечает. Можно ли это как-нибдуь обойти? Я не вижу никаких способов, потому как вызов захвата всё равно происходит из главного потока. И он всё равно должен ждать выхода из процедуры. |
Автор: Демо 5.6.2006, 13:26 |
Почему? |
Автор: IRQ 6.6.2006, 17:22 |
Ну как почему. Ведь я нажимаю кнопку. И обработчик ждёт возварата из процедуры. В которй как раз и происходит попытка захвата. И пока 5 секунд не пройдут, возврата не произойдёт. А значит кнопка так и не будет отжата. И приложение не убдет отвечать на запрсы новые. только потом. После 5 секнуд. |
Автор: Демо 7.6.2006, 14:40 |
IRQ, Так работай с ресурсами из дополнительных потоков. |
Автор: IRQ 8.6.2006, 14:36 |
Но ведь попытка захвата ресурсов делается всё равно по нажатию кнопки. И всё равно этот путь начинается отсюда. И обработчик должен ждать возвращения из процедуры захвата. Я же не могу просто так когду вздумается захватывать ресурсы. А по нажатию на кнопку. |