Question

J'ai un programme qui:

  • a un thread principal (1) qui démarre un thread de serveur (2) et un autre (4).
  • le thread du serveur (2) effectue un accept (), puis crée un nouveau thread (3) pour gérer la connexion.

À un moment donné, thread (4) fait un fork / exec pour exécuter un autre programme qui doit se connecter au socket que thread (2) écoute. Parfois, cela échoue ou prend un temps déraisonnablement long, et il est extrêmement difficile à diagnostiquer. Si je strace le système, il semble que le fork / exec a fonctionné, l'acceptation est arrivée, le nouveau thread (4) a été créé .. mais rien ne se passe dans ce thread (en utilisant strace -ff, le fichier du pid correspondant est vide).

Des idées?

Était-ce utile?

La solution

Je suis arrivé à la conclusion que c’était probablement ce phénomène:

http://kerneltrap.org/mailarchive/linux -kernel / 2008/8/15/2950234 / thread

car le bogue est difficile à déclencher sur nos systèmes de développement, mais il est généralement signalé par les utilisateurs qui s'exécutent sur de grandes machines partagées. De plus, l'application forkée démarre une machine virtuelle Java, qui alloue elle-même de nombreux threads. Le problème est également associé à la machine en cours de chargement et à une utilisation intensive de la mémoire (nous avons une machine avec 128 Go de RAM et les processus peuvent avoir une taille allant de 10 à 100 Go).

J'ai lu le livre O'Reilly pthreads, qui explique pthread_atfork () et suggère d'utiliser un "parent de substitution". processus créé à partir du processus principal au démarrage à partir duquel les sous-processus sont exécutés. Il suggère également l'utilisation d'un pool de threads pré-créé. Ces deux solutions semblent être de bonnes idées, je vais donc en implémenter au moins une.

Autres conseils

Cela ressemble à une impasse. Recherchez les fonctions de blocage, comme accept (), le problème devrait être là.

Réduisez le code à la plus petite taille possible qui a toujours le comportement et publiez-le ici. Soit vous trouverez la réponse, soit nous pourrons la retrouver.

BTW - http://lists.samba.org/archive /linux/2002-Février/002171.html , il semble que le comportement de pthread pour exec n’est pas bien défini et puisse dépendre de votre système d’exploitation.

Avez-vous un code entre fork et exec? Cela peut être un problème.

Soyez très prudent avec plusieurs threads et fork. La plupart des fichiers glibc / libstdc ++ sont thread-safe. Si un thread, autre que le forging, maintient un verrou lorsque fork exécute, le processus fork héritera des mutex dans leur état verrouillé actuel. Le nouveau processus ne verra jamais ces mutex déverrouillés. Pour plus d'informations, voir man pthread_atfork .

Je viens juste de tomber dans les mêmes problèmes et j'ai finalement trouvé que fork () duplique tous les threads . Maintenant, imaginez ce que votre programme fait après un fork () avec tous les threads exécutant une instance double ...

Les règles suivantes sont extraites de " A Mini -guide concernant fork () et Pthreads ":

  

1- Vous NE VOULEZ PAS faire cela.

     

2- Si vous avez besoin de fork (), alors:   dans la mesure du possible, insérez () tous vos   childs avant de commencer les discussions.   

Edit: essayé, fork () ne duplique pas les threads.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top