2015-04-17 1 views
1

J'ai un programme serveur simple, écrit en C sur Debian en utilisant la librairie pthread. Le programme gère la communication entre certains clients qui souhaitent partager des fichiers. Pour chaque client, il y a un thread de gestionnaire. Maintenant, à un certain point, chaque thread bloquera sur recv() en attente de toute demande de fichier client. Si l'un des clients demande un fichier spécifique, par un autre client, le serveur doit récupérer ce fichier auprès de son propriétaire, via son thread de gestionnaire, puis remettre le fichier au client qui l'a demandé, via son thread de gestionnaire. Comme tous les threads sont bloqués sur les appels recv(), comment peuvent-ils être remarqués par d'autres threads qu'ils doivent demander un fichier au client qu'ils traitent? Existe-t-il un moyen d '"interrompre" le recv(), de signifier la requête, puis de revenir à la fonction recv()?Programmation serveur Pthread: comment libérer un thread qui est bloqué sur un appel recv pour gérer une requête d'un autre thread

+0

Possède des sockets non bloquantes, et utilise 'select' /' poll'? –

+0

Malheureusement, l'une des exigences du projet est que les threads doivent bloquer sur le recv. Serait-il possible d'utiliser un signal SIGUSR1 pour interrompre le recv bloquant? – auserdude

+0

La partie délicate du mélange des threads et des signaux consiste à s'assurer que le signal est envoyé au bon thread. Non-bloquant recv() est une meilleure solution car un thread bloqué à l'intérieur de select() peut être réveillé proprement en lui envoyant un octet sur un autre socket. Cela dit, si vous devez essayer la route des signaux, voir ceci: http://stackoverflow.com/questions/2575106/posix-threads-and-signals –

Répondre

2

La façon classique de le faire est de créer un pipe() pour chaque fil, et au lieu de bloquer l'appel recv(), les blocs filetés à poll() contrôler à la fois la prise et le descripteur de fichier d'extrémité lecture du tube. Lorsque poll() renvoie, si le socket est lisible, appelez recv(); Si le tuyau est lisible, lisez-le et vérifiez les demandes des autres threads. Lorsque vous souhaitez effectuer une requête à un autre thread, vous pouvez le réactiver en écrivant dans le tuyau de ce thread.