2008-12-08 8 views
1

Il y a ConnectionManager qui attend les connexions entrantes. Pour chaque connexion entrante, elle crée une instance Connection qui gère le trafic entrant et sortant sur cette connexion. Chaque Connection a un Watchdog qui gère les conditions de "mauvaise connexion" et les appels enregistrés "Listerners". Un "Listener" est le ConnectionManager qui ferme la connexion et supprime l'instance Connection qui à son tour supprime le chien de garde correspondant.Problème de filetage (poursuite de votre propre queue)

Attendre. Une minute.

Le Watchdog appelle la ConnectionManager qui supprime le Connection qui supprime le Watchdog? Le chien de garde poursuit sa propre queue.

Je suis complètement bloqué. Comment résoudre ça?


Solution: Je ferai asynchrone Listener thingy barbante Je ne sais pas encore comment faire cela sans trop de douleur. Le Watchdog ne connaît pas le ConnectionManager. C'est assez générique. Aussi le Win32-Thread-API n'a pas quelque chose comme "join", donc je pourrais avoir besoin de rouler le mien avec GetExitCodeThread() et STILL_ACTIVE ...

Merci, les gars.

+0

Je suis confus par la question - si vous avez 1 chien de garde par connexion et que chien de garde est déclenchée, vous voulez la connexion (et son chien de garde associé) à supprimer, non? – LeJeune

Répondre

2

Si le chien de garde s'exécute dans un thread différent, alors le problème n'est pas trop grave - le chien de garde signale à ConnectionManager de supprimer avec un message asynchrone, puis quitte son propre thread.

Pendant ce temps, le thread ConnectionManager reçoit le message de suppression et commence à supprimer le chien de garde.

Pour éviter les conditions de course, le destructeur de chien de garde doit rejoindre le thread de surveillance et nettoyer le fil. (Probablement aussi signaler le thread de chien de garde, ou assert() quelque chose à propos de la thread de surveillance étant prêt à quitter).

3

Messagerie. Au lieu que l'appel Watchdog appelle une méthode ConnectionManager, envoyez un message à une file d'attente dans le gestionnaire de connexions. Cette file d'attente doit être thread-safe. Lorsque le ConnectionManager traite la file d'attente dans son thread, il est prudent d'attendre la fin du thread de connexion.

Watchdog   Queue    ConnectionManager 
    |    |      | 
Kill Connection---->|      | 
    |    |<-------------------Get Message 
    ---    |      | 
        |-------------------->Process Message 
        |      | 
        |      Kill Connection 
2

Si chacun de ces objets s'exécute dans son propre thread, il n'y a aucun problème.

Le chien de garde avertit le ConnectionManager et renvoie.
À ce stade, le thread Watchdog peut simplement quitter. Lorsque le ConnectionManager remarque l'événement watchdog, il tue le thread de connexion.

0

Si vous êtes attentif, il n'y a pas de problème.

  1. ConnectionInstance :: a_method() appelle chien de garde :: a_method() appelle ConnectionManager :: a_method

  2. ConnectionManager :: a_method() supprime ConnectionInstance supprime chien de garde

  3. ConnectionManager :: a_method () retourne à Watchdog :: a_method() retourne à ConnectionInstance :: a_method(). Tant que le chemin de retour n'accède à aucun membre, c'est juste un retour d'une fonction. Le code est toujours là par la norme, de sorte que vous pouvez revenir en toute sécurité.

Cela nécessite un codage et un entretien soigneux, mais ce n'est pas un hack sale.

protocole asynchrone exigera même quantité de pensée. Ce n'est pas seulement que vous devrez éviter de courir entre Watchdog demandant une suppression dans une file d'attente ConnectionManager :: et ConnectionManager faisant quelque chose avec la file d'attente en même temps. Le problème est plus profond: il y a une période où ConnectionInstance n'est pas fonctionnel - il a demandé à être supprimé - mais pas encore supprimé. Qu'est-ce que ça fait? Un code ne peut pas rester immobile. Si le ConnectionInstance n'est pas supprimé, vous pouvez également annuler la pile sans créer de protocoles asynchrones supplémentaires.

chien de garde lancer une exception pourrait être un moyen plus facile de traiter avec ConnectionInstance, si elles sont dans le même fil.

Questions connexes