Un sémaphore est un un moyen valide de le faire, mais pas nécessairement le meilleur. À chaque démarrage du programme X, appelez le ReleaseSemaphore
. Chaque fois qu'un processus se termine, appelez le WaitForSingleObject
avec un délai d'attente de zéro sur le descripteur de sémaphore (veillez également à l'inclure dans le gestionnaire d'exceptions, au cas où le programme tomberait en panne).
Le processus Y peut régulièrement interroger WaitForSingleObject
avec un délai d'attente de zéro (ou de quelques millisecondes). Si la valeur de retour est WAIT_OBJECT_0
, il doit relâcher le sémaphore immédiatement (autrement, il bloquera le dernier processus X en essayant de quitter!). Si la valeur de retour est WAIT_TIMEOUT
, il n'y a plus de processus X.
La solution mieux serait bien sûr de lancer tous les processus X de Y. Dans ce cas, Y pourrait tout WaitForMultipleObjects
sur le processus gère qu'il obtient de CreateProcess
sans supplémentaires « si et whens ». Cela fonctionnera toujours, toujours. C'est plus efficace aussi.
Ce qui conduit à la deuxième meilleure solution ... obtenir des poignées pour les processus en cours avec OpenProcess
et WaitForMultipleObjects
sur ceux-ci. Le problème est de savoir d'où proviennent les ID de processus. Une zone de mémoire partagée pourrait faire l'affaire, un tuyau pourrait faire l'affaire, ou CreateToolhelp32Snapshot
pourrait vous donner cette information.
Une autre façon serait d'utiliser un objet mutex nommé. Tous les processus X appellent CreateMutex
. Si le mutex existe déjà, aucun dommage n'est fait (GetLastError retournera ERROR_ALREADY_EXISTS
, mais alors quoi?). Si le processus se termine ou tombe en panne, tous les descripteurs ouverts sont fermés et le nombre de références mutex est donc décrémenté.
Le processus Y appelle OpenMutex
. Cela réussit ou échoue. S'il réussit, il ferme à nouveau le handle, dort, et essaie à nouveau. En cas d'échec, aucun processus X n'est en cours d'exécution. Encore une autre façon (bien qu'elle pourrait avoir des problèmes de course) serait de créer un segment de mémoire partagée nommé et d'appeler InterlockedIncrement
et InterlockedDecrement
au début et à la sortie du processus X. Le processus Y sait qu'aucun processus X n'est en cours d'exécution si l'objet de mémoire partagée ne peut pas être ouvert ou si le compteur est zéro.