Bonjour à tous,

Afin de tester l'utilisation de la primitive fork, j'ai écris ce petit programme :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>

int main(void){
        struct timeval timestamp;

        if(fork()){
                /**** Père ****/
                int retour;
                gettimeofday(&timestamp,NULL);
                printf("Je suis le père, timestamp : %d.%d\n",(int)timestamp.tv_sec,(int)timestamp.tv_usec);
                wait(&retour);
                printf("Fils mort, code : %d\n",retour);
        }
        else{
                /**** Fils ****/
                gettimeofday(&timestamp,NULL);
                printf("Je suis le fils, timestamp : %d.%d\n",(int)timestamp.tv_sec,(int)timestamp.tv_usec);
                printf("suicide !\n");
                exit(1);
        }
        return 0;
}
D'après mon cours, juste après le fork, le fils devrait s'exécuter avant le père. Or lorsque je teste ce programme sur un noyau 2.6.35 ( de Fedora 14), j'ai le père qui s’exécute en premier...
Je suis le père, timestamp : 1318267786.474512
Je suis le fils, timestamp : 1318267786.474590
suicide !
Fils mort, code : 256
alors que sur un 2.6.18 (centos 5) on a bien le comportement escompté.
Je suis le fils, timestamp : 1318268002.606678
suicide !
Je suis le père, timestamp : 1318268002.606790
Fils mort, code : 256
Il y aurait-il eu un changement de politique dans le gestion du fork ? Quel en est la raison ?

Merci d'avance,

Mongos
Tu es sûr de toi ? Après le fork, il y a deux processus, je ne vois pas comment tu pourrais avoir la garantie que l'un s'exécute avant l'autre.
Sûr de moi, non. Je ne fais que citer mon cours qui dit que pour des raisons de performance, le fils serait exécuté en premier (copy on write). J'ai fait le tests sur plusieurs noyaux. Pour les noyaux 2.6.35+, toujours le père est exécuté en premier, pour les noyaux 2.6.18- c'est toujours le fils. Les résultats sont assez constants tout de même.
Pour moi c'est purent aléatoire.
En effet, les résultats sont constants chez moi aussi. C'est une bonne question à poser à ton prof :-D Cela dit ça n'a pas d'importance pour celui qui utilise le fork.
WilQu wrote:En effet, les résultats sont constants chez moi aussi. C'est une bonne question à poser à ton prof :-D Cela dit ça n'a pas d'importance pour celui qui utilise le fork.
Malheureusement, il n'a pas pu me répondre ^^" Du coup je cherche la réponse !
Alors oui dans la plus part des cas, cela n'a pas d'importance. Mais, cela n'empêche ma volonté de comprendre le fonctionnement, ne serait-ce que par curiosité.
Désolé, mais ton cours dit une connerie.

D'une part sur le principe, ce n'est pas déterministe.
Suivant l'OS (*Linux, *BSD, *nix, Mach, etc...) ça peut l'un, l'autre, ou l'un ou l'autre ...

D'autre part, encore faudrait-il savoir si ta machine est mono ou multi-core.
Sur un mono core, ça pourrait être déterministe, mais sur un muti-core ... niet !
philippe_PMA wrote:[....]
D'une part sur le principe, ce n'est pas déterministe.
Suivant l'OS (*Linux, *BSD, *nix, Mach, etc...) ça peut l'un, l'autre, ou l'un ou l'autre ...
[...]
Mon cours ne concerne que Linux, et les tests que j'ai fait n'ont été fait que sous Linux bien entendu.
philippe_PMA wrote:[....]
D'autre part, encore faudrait-il savoir si ta machine est mono ou multi-core.
Sur un mono core, ça pourrait être déterministe, mais sur un muti-core ... niet !
Effectivement, je ne me suis pas posé la question du multi-core. Mais (oui je suis chiant 🙂) ayant fait les tests sur mon portable (mono-core) (testé en 2.6.18, 2.6.35, 2.6.40), sur mon fixe (dual-core)(testé en 2.6.18, 2.6.35) et sur un serveur dual-core (2.6.18), les résultats restent constant....à moins que je n'ai vraiment pas de chance dans mes tests....cela ne semble pas avoir réellement d'influence (dans ce cas là en tout cas).
Tu a testé avec différente charge ?
sinon juste pour info, le printf c'est pas atomic
Il n'y avait pas eu un changement pour une meilleure gestion de fork ?
Car dejà depuis le 2.6.32, la politique du child run first a été désactivé par défaut car elle n'apportait pas plus de gain vu l'évolution des CPU, le TLB (translation lookaside buffer) ayant un meilleur rendement en continuant l'exécution du processus père à la suite du fork() (edith pas de frok()).
ben51 wrote:Tu a testé avec différente charge ?
Bis.
si une interruption, une fin d'IO ou que sais-je nécessite d'être traité, ça va changer le déroulement de l'exécution ....
ben51 wrote:Tu a testé avec différente charge ?
Oui absolument, on a une très forte tendance (de l'ordre de 95%) du fils en premier pour les 2.6.18 et du père en premier pour les 2.6.35+, quelque soit le processeur.
Toinou87 wrote:sinon juste pour info, le printf c'est pas atomic
D'où la présence du timeval qui sert de témoin.

Refuznik wrote:Il n'y avait pas eu un changement pour une meilleure gestion de fork ?
Car dejà depuis le 2.6.32, la politique du child run first a été désactivé par défaut car elle n'apportait pas plus de gain vu l'évolution des CPU, le TLB (translation lookaside buffer) ayant un meilleur rendement en continuant l'exécution du processus père à la suite du fork() (edith pas de frok()).
Merci, c'est justement ce que je voulais savoir 🙂 Je pense que j'ai eu ma réponse donc,

Merci encore à tous pour votre aide !