ждать последнего экземпляра программы - PullRequest
2 голосов
/ 13 июля 2011

У меня есть две программы, X - обычная программа, с которой взаимодействует пользователь, и программа Y, которая очищает ресурсы, полученные программой Y. Может быть несколько экземпляров X, но только один из Y (я уже решил эту частьс именованными мьютексами).Теперь, поскольку Y - программа очистки, она должна быть заблокирована до исчезновения последнего экземпляра X.

Я пытался использовать семафор, но я не мог понять это.Кто-нибудь может мне помочь?

1 Ответ

1 голос
/ 13 июля 2011

Семафор - один допустимый способ сделать это, но не обязательно лучший.Каждый раз, когда запускается программа X, звоните ReleaseSemaphore.Всякий раз, когда процесс завершается, вызывайте WaitForSingleObject с нулевым тайм-аутом для дескриптора семафора (обязательно включите его в обработчик исключений в случае сбоя программы).
Процесс Y может регулярно опрашивать WaitForSingleObject стайм-аут нуля (или нескольких миллисекунд).Если возвращаемое значение равно WAIT_OBJECT_0, он должен немедленно немедленно освободить семафор (иначе он заблокирует последний X-процесс, пытающийся выйти!).Если возвращаемое значение равно WAIT_TIMEOUT, то больше нет процессов X.

Лучшим решением best будет, конечно, запуск всех процессов X из Y. В этом случае Y можетпросто WaitForMultipleObjects в обработчиках процесса, которые он получает из CreateProcess без лишних «если и когда».Это будет "просто работать", всегда.Он также более эффективен.
Что приводит ко второму наилучшему решению: получить управление запущенными процессами с OpenProcess и WaitForMultipleObjects.Проблема в том, где взять идентификаторы процессов.Общая область памяти может подойти, канал может сделать, или CreateToolhelp32Snapshot может дать вам эту информацию.

Другим способом будет использование именованного объекта мьютекса.Все процессы X называют CreateMutex.Если мьютекс уже существует, никакого вреда не будет (GetLastError вернет ERROR_ALREADY_EXISTS, но что с того).Если процесс завершается или завершается сбоем, все открытые дескрипторы закрываются, и, таким образом, счетчик ссылок мьютекса уменьшается.
Процесс Y вызывает OpenMutex.Это либо успешно, либо неудачно.Если это удается, он снова закрывает ручку, спит и пытается снова.В случае сбоя ни один из процессов X не запускается.

Еще одним способом (хотя могут быть проблемы с расой) было бы создание именованного сегмента совместно используемой памяти и вызов InterlockedIncrement и InterlockedDecrement при запуске процесса Xи выход.Процесс Y знает, что X-процессы не выполняются, если либо объект общей памяти не может быть открыт, либо счетчик равен нулю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...