Семафор - один допустимый способ сделать это, но не обязательно лучший.Каждый раз, когда запускается программа 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-процессы не выполняются, если либо объект общей памяти не может быть открыт, либо счетчик равен нулю.