11
votes

C - L'EXEC doit-il immédiatement suivre la fourche dans un processus multi-threadé?

Situation: J'ai un programme multithread écrit en C. Si l'un des files de threads, le processus enfant est remplacé par un autre à l'aide de EXED () et le parent attend que l'enfant quitte.

problème: Une fois le processus enfant créé par Fork (), il existe quelques lignes de code qui compilent les arguments à utiliser dans la commande EXED () suivante.

hypothèse Ai-je raison de supposer que dans le temps entre le processus d'enfant créé par Fork () et être remplacé par EXED (), le processus d'enfant - être une copie du parent - aura tous les fils du parent et donc ces threads va courir - bien que pendant une très brève période?

Si oui, est la solution correcte pour appeler Exec () immédiatement après la fourchette ()?


0 commentaires

3 Réponses :


11
votes

Seul le thread qui appelle fourchette seront en cours d'exécution dans le nouveau processus. Cependant, il y a des limites auxquelles les fonctions que vous pouvez appeler avant exec . De fourchette :

Un processus doit être créé avec seul fil. Si un multithread les appels de processus de fork () , le nouveau processus contient une réplique de l'appel fil et son espace d'adressage ensemble, y compris éventuellement les états de mutex et d'autres ressources. Par conséquent, pour éviter les erreurs, les processus enfant ne peut exécuter opérations asynchrones signal de sécurité jusqu'à ce que ce que l'un des exec Fonctions est appelé. Fourchette Chariot peuvent être établies au moyen de la fonction pthread_atfork () afin de maintenir l'application invariants à travers fork () appels.

Je crois que cela signifie que vous devez généralement être d'accord, tant que tout multi-thread bibliothèques utilisent pthread_atfork correctement.

EDIT: pthread_atfork explique en outre comment la bibliothèque peut se protéger:

L'utilisation prévue est que le préparer gestionnaire acquiert tous les verrous mutex et les deux autres gestionnaires de fourche libèrent les.

Par exemple, une application peut fournir une routine qui acquiert préparer la mutex nécessaires à la bibliothèque maintient et de l'enfant et le parent d'approvisionnement routines qui libèrent les mutex, assurant ainsi que l'enfant obtient un image cohérente de l'état de la bibliothèque (et qu'aucun mutex gauche brin). Par ailleurs, certains les bibliothèques pourraient être en mesure de fournir tout une routine d'enfant qui réinitialise le mutex dans la bibliothèque et tous états associés à une valeur connue (Par exemple, ce qu'il était lorsque le image a été exécuté à l'origine).


2 commentaires

Est le passage cité suggérant que la bibliothèque standard (par exemple, STDIO, atexit , MALLOC , la création et la destruction de threads, etc.) peut utiliser à l'interne les ressources de synchronisation pouvant être dans Un état incohérent après Fourchette ? Si oui, comment utiliserait pthread_atfork résoudre le problème?


@R, oui, éventuellement. Cela dépend de la bibliothèque. Dans certains cas, ils peuvent verrouiller toutes les mutiles pré-fourchettes, puis les libérer immédiatement après la fourche. Dans d'autres, il est normal de les réinitialiser comme si le processus commence à partir de zéro. J'ai ajouté un passage pertinent de pthread_atfork .



3
votes

Comme @Matthew a écrit dans sa réponse, les autres threads du processus parent n'existeront pas dans le processus d'enfant (si vous utilisez Pthreads).

Notez que si ce n'était pas le cas, cela ne vous aiderait pas à placer l'appel d'EXED () "immédiatement après" l'appel à la fourche, car il y aurait toujours la possibilité que les autres threads fonctionnent avant l'appel à l'exécutif (). Cependant, vous pouvez contrôler cela en verrouillant un mutex avant d'appeler Fork () - il serait essentiellement détruit par l'appel à EXEC ().


1 commentaires

Je ne suis pas sûr que cela soit correct sur les mutiles "essentiellement détruits". Comme je l'ai dit ci-dessus, il y a un risque que les serrures entrent dans un état incohérent. C'est pourquoi pthread_atfork existe.



0
votes

J'ai aussi pensé, tous les threads seront également reproduits dans le processus d'enfant. Mais ce n'est pas vrai. Étant donné que d'autres threads ne sont pas répliqués dans le processus d'enfant, si vous utilisez des mutiles / serrures avant exécutant, vous devez vous assurer que les gestionnaires de fourchettes sont écrits pour les gérer correctement. Voici un article sur celui-ci. http: // LearnwithTechies .com / tech / index.php? Option = com_content & View = Article & ID = 15: Fourche-in-multhrouded-Environnement & Catid = 10: Unix


0 commentaires