2010-11-09 2 views
3

J'essaie d'utiliser l'objet événement dans l'environnement win32 pour synchroniser deux processus. Voici le code simplifié de deux programmes.Utilisation de l'objet événement dans l'inter-processus

// process1 
int main() 
{ 
    HANDLE h = CreateEvent(NULL, FALSE, FALSE, TEXT("Hello")); 
    WaitForSingleObject(h, INFINITE); 
// RunProcess(L"process2.exe", L""); 
} 

// process2 
int main() 
{ 
    HANDLE h = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("Hello")); 
    SetEvent(h);  
} 

C'est assez simple et fonctionne bien lorsque deux processus sont lancés indépendamment. Cependant, cela ne fonctionne pas lorsque le processus 1 lance le processus 2 en tant que processus enfant (ce qui est commenté dans le code ci-dessus) - l'appel SetEvent échoue. Quelle est la raison et la solution de ce problème?

Répondre

3

Votre code doit vérifier et gérer les erreurs. Les deux CreateEvent et OpenEvent renverront NULL s'ils échouent, dans ce cas vous devez vérifier l'erreur en utilisant GetLastError.

Vos appels à WaitForSingleObject et SetEvent doivent également être vérifiés par les documents MSDN.

L'ordre dans lequel vous devez faire les choses dans le processus parent est:

  • CreateEvent
  • processus enfant Début
  • WaitForSingleObject.

Sinon, vous rencontrerez le problème signalé par @Mark Tolonen.

Il est également préférable d'avoir un délai d'attente sur votre attente, pour gérer le cas où le processus enfant ne démarre pas, se ferme de façon inattendue ou se bloque.

Une approche alternative si vous envisagez d'utiliser cette relation parent/enfant consisterait à autoriser l'héritage du handle d'événement. Ensuite, l'événement n'a pas besoin d'être nommé, et personne d'autre ne peut le «squatter» dans une attaque DoS sur vos applications. Vous pouvez transmettre la valeur du descripteur à l'enfant en tant que paramètre de ligne de commande. Pour ce faire, utilisez le champ bInheritHandle sur le paramètre eventAttributes à CreateEvent.

Une valeur booléenne qui indique si la poignée de retour est transmise lorsque un nouveau processus est créé. Si ce membre est VRAI, le nouveau processus hérite du handle.

+0

Merci pour votre réponse détaillée!Le problème a été résolu par magie - cela fonctionne finalement aujourd'hui, sans modification du code. :(Bien que je pense que je devrais écrire un code de gestion des exceptions et vous m'avez beaucoup aidé. – summerlight

1

Etes-vous sûr? Comme écrit, si process1 crée process2 dans l'emplacement actuel, il ne créera jamais process2 car il attendra toujours que l'événement soit déclenché. Créez d'abord process2, puis attendez que l'événement soit défini.

+1

Ah, c'est mon erreur - le code original est plus complexe et j'ai fait une erreur pendant que je simplifie le code. :(Le code commenté doit être placé au-dessus de WaitForSingleObject comme vous l'avez dit – summerlight

+0

Tant que la question reste inchangée, cette réponse est tout simplement correcte :-) – Wolf

2

Vous avez un descripteur de sécurité NULL, qui dit la documentation ne peut pas permettre à la poignée d'être héritée par les processus enfants, en particulier:

If this parameter is NULL, the handle cannot be inherited by child processes

Peut-être que vous devez créer un descripteur de sécurité approprié?

Questions connexes