2010-04-11 4 views
3

HI
J'écris une partie d'un serveur qui devrait envoyer d'autres processus fils.
Parce que je veux attendre sur certains processus, et distribuer d'autres sans attendre l'achèvement, j'utilise double fork pour le second type de processus (évitant ainsi les processus zombies).
Le problème est, mon serveur contient beaucoup de mémoire, donc le forking prend beaucoup de temps (même la copie-sur-écriture utilisée dans Linux qui ne copie que les tables de pagination)
Je veux remplacer la fourche() par vfork(), et c'est facile pour la deuxième branche (car elle n'appelle que execve() dans l'enfant), mais je n'ai trouvé aucun moyen de remplacer la première.
Est-ce que quelqu'un sait comment je peux faire ça?
Merci!double fourche en utilisant vfork

Le serveur est un linux (RH5U4) écrit en C++.

Répondre

1

vfork() ne peut être utilisé pour fork, puis appelez exec ou exit. En outre, vfork() va bloquer le processus parent jusqu'à ce que l'enfant appelle _exit ou exec, ce qui n'est certainement pas le comportement que vous voulez.

La raison en est que vfork() ne fait aucune copie des données, y compris la pile, pour le nouveau processus. Tout est donc partagé, et il est très facile de changer accidentellement quelque chose que le processus parent ne peut pas gérer. Comme les données sont partagées sans copies, le processus parent ne peut pas continuer à s'exécuter en même temps que l'enfant. Il doit donc attendre _exit ou appeler le exec afin qu'il n'utilise plus les données lorsque le parent commence à les modifier.

+0

Merci, SoapBox. Mais je cherche une solution de contournement qui me permettra de doubler la fourchette sans le coût supplémentaire de fork() –

+1

C'est '_exit' pas' exit'. Vous ne pouvez définitivement pas appeler 'exit' après' vfork'. –

2

Pourquoi ne pas simplement demander au nouveau processus exec'd de faire lui-même une autre branche? De cette façon seulement un petit processus simple aura ses tables de pages copiées?

EDIT:

Bien sûr, le parent aurait à faire une attente de courte durée() pour nettoyer le zombie de celui-là, mais le processus de petit-enfant pourrait alors fonctionner aussi longtemps qu'il voulait.

1

Je pense que ce que vous voulez vraiment faire est de faire usage de SIGCHLD et de maintenir une liste de processus fils. Vous pouvez ensuite supprimer la double fourche en notifiant votre processus principal lorsque les enfants changent d'état (la plupart du temps, lorsqu'ils meurent) et effectuez une action sur eux en fonction de cela. Vous pouvez également garder trace de l'un de vos processus fils plus longtemps que prévu (car vous avez stocké leur temps de création dans votre liste) et prendre des mesures si elles deviennent folles et ne se terminent jamais.

1

Ne doublez pas la fourche. Gérer SIGCHLD pour sauvegarder errno, appeler wait, restaurer errno.