Arrêt d’un thread récepteur bloquant sur recv ()

J’ai une application de discussion qui a un fil séparé pour écouter les messages entrants.

while (main thread not calling for receiver to quit) { ssortingng message = tcpCon.tcpReceive(); // Relies on the recv() function processIncomingMessage(message); } 

Cette façon de travailler a un gros problème. La plupart du temps, la boucle bloquera sur recv() afin que le thread récepteur ne se ferme pas. Quel serait le bon moyen de résoudre ce problème sans forcer la fin du thread après quelques secondes?

Fermez le socket avec shutdown() pour le fermer pour tous les récepteurs.

Ceci affiche ‘recv a renvoyé 0’ sur mon système, indiquant que le récepteur a vu un arrêt normal. Mettez en commentaire shutdown() et regardez-le se bloquer pour toujours.

À plus long terme, OP devrait corriger la conception, en utilisant select ou en incluant un message de fermeture explicite dans le protocole.

 #include  #include  #include  #include  #include  #include  /* Free on my system. YMMV */ int port = 7777; int cd; void *f(void *arg) { /* Hack: proper code would synchronize here */ sleep(1); /* This works: */ shutdown(cd, SHUT_RDWR); close(cd); return 0; } int main(void) { /* Create a fake server which sends nothing */ int sd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in sa = { 0 }; const int on = 1; char buf; pthread_t thread; sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = htons(port); setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on); /* Other error reporting omitted for clarity */ if (bind(sd, (const struct sockaddr*)&sa, sizeof sa) < 0) { perror("bind"); return EXIT_FAILURE; } /* Create a client */ listen(sd, 1); cd = socket(AF_INET, SOCK_STREAM, 0); connect(cd, (const struct sockaddr*)&sa, sizeof sa); accept(sd, 0, 0); /* Try to close socket on another thread */ pthread_create(&thread, 0, f, 0); printf("recv returned %d\n", recv(cd, &buf, 1, 0)); pthread_join(thread, 0); return 0; } 

Vous pouvez utiliser select () pour attendre les données entrantes et éviter le blocage dans recv (). select () bloquera également, mais vous pouvez le faire expirer après un intervalle défini de sorte que la boucle while puisse continuer et vérifier les signaux à quitter du thread principal:

 while (main thread not calling for receiver to quit) { if (tcpCon.hasData(500)) { // Relies on select() to determine that data is // available; times out after 500 milliseconds ssortingng message = tcpCon.tcpReceive(); // Relies on the recv() function processIncomingMessage(message); } } 

Si vous fermez le socket dans un autre thread, alors recv () se fermera.

appeler close sur le socket depuis n’importe quel autre thread fera que l’appel recv échouera instantanément.