2010-12-04 16 views
0

Je crée un thread à recevoir sur un socket bloquant, il attend que les paquets arrivent. Cependant, lorsque j'essaie de me déconnecter du thread primaire, des conditions de concurrence se produisent entre les threads, ce qui conduit à des erreurs.Multithreading - Déconnexion de la connexion TCP

Ici, le commutateur se produit à la ligne 5 entre les threads sans réellement terminer l'appel de déconnexion. Comment devrais-je éviter les commutateurs et laissez-le gracieusement terminer l'appel de déconnexion?

Répondre

1

Voici deux solutions possibles.

Vous pouvez isoler TOUS les accès socket dans le thread socket (non primaire), et au lieu de déconnecter le socket du thread primaire, avoir ce thread le thread non-primaire qui déconnecter (ou une autre action) est nécessaire . Cela obligerait votre thread secondaire à attendre sur deux objets - le socket, et un signaller (Win32 Event, par exemple) qui indique une déconnexion est nécessaire. Si d'un autre côté vous voulez autoriser le thread primaire à se déconnecter (comme vous le faites maintenant), vous devez vérifier tout votre code qui utilise le socket, et le rendre thread-safe en utilisant des verrous pour assurer un accès simultané à le socket et les données d'état associées sont évitées. Boost.Thread a des verrous appropriés que vous pouvez utiliser ici, sinon vous pouvez implémenter votre propre comme un wrapper sur quelque chose comme Win32 CriticalSection.

La seconde serait ma solution préférée - le fait que vous posiez cette question signifie que vous devez revenir en arrière et penser à la sécurité du fil dans votre conception de toute façon. Même si vous allez avec la première idée ci-dessus, vous devez toujours maintenir l'état pour éviter que plusieurs signaux de déconnexion soient envoyés à partir du thread principal, et cela devrait être verrouillé. De plus, si vous souhaitez que le thread non primaire traite les événements entrants autres que 'disconnect', il y aura un état associé qui devra être géré entre les threads.

Je pense que le chemin de la moindre résistance d'où vous êtes maintenant est d'ajouter le verrouillage à votre code existant. Assurez-vous de limiter le plus possible vos verrous - ne configurez pas un verrou que vous maintenez sur un appel de socket qui peut bloquer ou prendre beaucoup de temps, par exemple.

+0

Dans le thread secondaire, j'ai une boucle while sans fin appelant receive() pour vérifier les messages et Dans cet appel de réception, il y a un blocage de recv() en attente d'un message. Comment pourrais-je le signaler pendant qu'il attend sur socket? – user963241

+0

Vous pouvez utiliser une boucle sur WaitForSingleObject (terminateEvent) et conserver une réception asynchrone toujours affichée. C'est une autre bonne raison pour laquelle la deuxième approche est probablement moins douloureuse pour vous, comme je l'ai noté. –

+0

J'ai mis SetEvent() et ResetEvent() au début et à la fin de disconnect() et un certain temps (WaitForSingleObject (terminateEvent, 0) == WAIT_TIMEOUT) pour vérifier les verrous au lieu de isConnected booléenne. Cela fonctionne mais je suppose que c'est ce que vous voulez vraiment dire. – user963241