Pourquoi ce programme d'impression “en fourche!” 4 fois?
Pourquoi ce programme d'impression “en fourche!” 4 fois?
#include <stdio.h>
#include <unistd.h>
int main(void) {
fork() && (fork() || fork());
printf("forked!\n");
return 0;
}
Mon pari est que le (s)qu'il ne savait pas à propos de court-circuit de l'évaluation ou il enchevêtrée avec la valeur de retour de
fork()
@LightnessRacesinOrbit.OriginalL'auteur rona-altico | 2014-11-03
Vous devez vous connecter pour publier un commentaire.
La première
fork()
renvoie une valeur non nulle dans le processus appelant (appel il p0) et 0 dans l'enfant (appelons p1).En p1 le court-circuit pour
&&
est pris et le processus d'appelsprintf
et se termine. En p0, le processus doit évaluer le reste de l'expression. Ensuite, il appellefork()
de nouveau, ainsi, de créer un nouveau processus enfant (p2).En p0
fork()
renvoie une valeur non nulle, et le court-circuit pour||
est pris, de sorte que le processus d'appelsprintf
et se termine.En p2,
fork()
retourne 0 si le reste de l' || doit être évalué, ce qui est la dernièrefork()
; qui mène à la création d'un enfant pour p2 (appelons-p3).P2 exécute alors
printf
et se termine.P3 exécute alors
printf
et se termine.4
printf
s sont ensuite exécutées.consultez le lien sur court-circuit dans ma réponse. Cela signifie essentiellement que si le premier opérande de
&&
est de zéro, l'autre opérande(s) ne sont pas évalués. Sur la même logique, si un opérande d'un||
est 1, alors le reste des opérandes pour ne pas avoir besoin d'évaluation. Cela se produit parce que le reste des opérandes ne peut pas changer le résultat de la logique de l'expression, de sorte qu'ils n'ont pas besoin d'être exécuté, nous avons donc gagner du temps. Mieux maintenant rona? Belle question en passant, je ne vois pas pourquoi les downvotes. Vous gtot mes +1.J'ai du mal à comprendre pourquoi vous voulez les utiliser
fork()
, mais ne savent même pas ce que le court-circuit est. Était-ce une question à l'école?Je suppose que c'est downvoted parce que c'est l'un des nombreux doublons, et ne montre aucun effort même de chercher sur google avant de demander ici.
Vous ne pouvez pas voir pourquoi les downvotes? C'est un terrible question. Il est une copie exacte et il n'a pas pris la peine d'expliquer quels sont les différents sortie il l'avait prévu. Pourquoi cela a 41 upvotes est entièrement au-delà de moi; en général, ce genre de chose arrive vite à -3 ou -4.
OriginalL'auteur Jean-Baptiste Yunès
L'on vient de
main()
et les trois autres de chaquefork()
.Notez que tous les trois
forks()
vont être exécutés. Vous voudrez peut-être jeter un oeil à la ref:Notez que l'id de processus ne peut pas être égal à zéro, comme indiqué ici.
Donc ce qui se passe vraiment?
Nous avons:
Donc la première
fork()
sera de retour à la mère de sa non nul, l'id du processus, alors qu'il sera de retour 0 pour le processus de l'enfant. Cela signifie que l'expression logique de la première fourche sera évaluée à true dans le processus parent, tandis que dans le processus de l'enfant, elle sera évaluée à false et que, en raison de Court-circuit de l'évaluation, il ne sera pas appeler les deux autresfork()
s.Maintenant, on sait qu'on va recevoir au moins deux tirages (un principal et un de la 1ère
fork()
).Maintenant, le 2ème
fork()
dans le processus parent va être exécutée, elle est et elle renvoie une valeur non nulle pour le processus parent et un zéro dans le processus de l'enfant.Alors maintenant, le parent ne se poursuivra pas l'exécution de la dernière
fork()
(par court-circuit), tandis que le processus enfant d'exécuter la dernière fourche, depuis le premier opérande de||
est de 0.Cela signifie donc que nous aurons plus de deux tirages.
Comme un résultat, nous obtenons quatre tirages au total.
Court-circuit
Ici, court-circuit signifie essentiellement que si le premier opérande de && est zéro, alors l'autre opérande(s) est/ne sont pas évalués. Sur la même logique, si un opérande d'un || est-1, puis le reste de la opérandes n'avez pas besoin d'évaluation. Cela se produit parce que le reste de la opérandes ne peut pas changer le résultat de la logique de l'expression, de sorte qu'ils n'ont pas besoin d'être exécuté, donc nous gagnons du temps.
Voir l'exemple ci-dessous.
Processus
Rappelez-vous qu'un processus père crée la descendance des processus qui, à leur tour, créent des les autres processus et ainsi de suite. Cela conduit à une hiérarchie de processus (ou d'un arbre que l'on pourrait dire).
Ayant ceci à l'esprit, il vaut la peine de prendre un coup d'oeil à ce problème similaire, ainsi que cette réponse.
Descriptif de l'image
J'ai fait aussi cette figure qui peut aider, je suppose. J'ai supposé que le pid du
fork()
retournés sont 3, 4 et 5 pour chaque appel.Notez que certains
fork()
s X rouge au-dessus d'eux, ce qui signifie qu'ils ne sont pas exécutées à cause du court-circuit de l'évaluation de l'expression logique.La
fork()
s en haut ne sont pas va être exécuté, car le premier opérande de l'opérateur&&
est 0, donc l'ensemble de l'expression sera résultat en 0, donc pas d'essence dans l'exécution du reste de l'opérande(s) de&&
.La
fork()
au fond ne sera pas exécuté, car c'est la deuxième opérande d'une||
, où son premier opérande est un nombre différent de zéro, donc le résultat de l'expression est déjà évalué à vrai, peu importe ce que le deuxième opérande est.Et dans l'image suivante vous pouvez voir la hiérarchie des processus:
basé sur la figure précédente.
Exemple de Court-Circuit
De sortie:
OriginalL'auteur gsamaras
Pour tous les downvoters, c'est à partir d'une fusion mais une autre question. Le blâme. Merci à vous.
Vous pouvez décomposer le problème à trois lignes, la première et la dernière lignes à la fois tout simplement le double du nombre de processus.
Les opérateurs de court-circuit, donc, c'est ce que vous obtenez:
C'est donc en tout 4 * 5 = 20 processus d'impression d'une ligne.
Remarque: Si pour une raison quelconque (fork () échoue (par exemple, vous avez une limite sur le nombre de processus), il renvoie -1 et ensuite, vous pouvez obtenir des résultats différents.
Et aussi fork1() || fork2() && fork3(); cette déclaration de résultats dans 16 processus.
oui, 5 fois. oui, 16 si les deux autres fourches sont là aussi.
Salut @yi_H suis juste confondre comment "fork1() || fork2() && fork3 (en)" résultats dans 16 au total . Je veux dire, je peux avoir un schéma comme celui-ci que vous avez mentionné ci-dessus
Ceci répond à la question qui utilise
fork() && fork() || fork();
, alors que la question ici utilisefork() && (fork() || fork());
. Il y avait une fusion, comme expliqué ici: meta.stackoverflow.com/questions/281729/...". Vous pouvez modifier votre réponse, en en informant les futurs lecteurs.OriginalL'auteur Karoly Horvath
L'exécution de
fork() && (fork() || fork())
, ce qui se passeChaque
fork
donne 2 processus avec respectivement des valeurs de pid (parent) et 0 (enfant)Première bifurcation :
&& (fork() || fork())
||
partie => printforked
|| fork()
forked
forked
forked
Total : 4
forked
OriginalL'auteur Serge Ballesta
J'aime toutes les réponses qui ont déjà été soumis. Peut-être que si vous avez ajouté un peu plus de variables à votre instruction printf, il serait plus facile pour vous de voir ce qui se passe.
Sur ma machine, il produit la sortie suivante:
long f1,f2,f3; (f1 = fork()) && ((f2 = fork()) || (f3 = fork()));
et ensuite imprimer le PID et les trois valeurs individuelles.OriginalL'auteur Bradley Slavik
Ce code:
obtient 20 processus pour lui-même et 20 fois Printf va aller.
Et pour
printf ira un total de 5 fois.
fork() && fork() || fork();
, alors que la question ici utilisefork() && (fork() || fork());
. Il y avait une fusion, comme expliqué ici: meta.stackoverflow.com/questions/281729/...". Vous pouvez modifier votre réponse, en en informant les futurs lecteurs.OriginalL'auteur Mayank Dixit