IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

eclaircissement sur fonctionnement programme c


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Points : 42
    Points
    42
    Par défaut eclaircissement sur fonctionnement programme c
    Bonsoir à tous, j'aimerai avoir un petit éclaircissement sur le fonctionnement de mon programme c :
    Voici le programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
     
    int i=10;
    f() {printf("%d\n",i++);}
    g() {f();fork();f();}
     
     
    int main ()
    {
     
      g();g();
     
    }
    Donc après compilation puis lancement (./test), j'obtiens :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    11
    12
    13
    13
    13
    J'ai envie de dire normal (vu mon programme).

    Maintenant si je fais :
    J'obtiens dans mon fichier toto :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    10
    11
    12
    13
    10
    11
    12
    13
    10
    11
    12
    13
    10
    11
    12
    13
    Enfin si je fais
    J'obtiens Ma question est donc, pourquoi une telle différence dans ce qui est affiché dans mon terminal et ce qui se met dans le fichier toto ? Pourquoi mon wc affiche 16 et non 9 ?

    Autant de questions qui me troublent :s

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Amusant comme problème !!

    Avant de me lancer dans de longues explications, est ce que tu peux modifier ta fonction f() comme cela ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #include <unistd.h> 
    f() {printf("%5d:%5d %d\n", getppid(), getpid(), i++);}
    Tu recompiles et tu repostes les mêmes tests et après on discute.

    Car là, sans les identifiants de process, cela ne va être que des suppositions.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Points : 42
    Points
    42
    Par défaut
    Ha je savais que ça pouvait être marrant comme problème lol.

    Donc voilà mes test :
    en éxécutant le programme :
    8135: 8345 10
    8345: 8346 11
    8345: 8346 12
    8346: 8347 13
    8135: 8345 11
    8135: 8345 12
    8345: 8348 13
    8345: 8346 13
    8135: 8345 13
    avec le ./test | wc -l

    toujours 16

    et mon toto contient :

    8135: 8636 10
    8636: 8637 11
    8636: 8637 12
    8637: 8638 13
    8135: 8636 10
    8636: 8637 11
    8636: 8637 12
    8636: 8637 13
    8135: 8636 10
    8135: 8636 11
    8135: 8636 12
    8636: 8639 13
    8135: 8636 10
    8135: 8636 11
    8135: 8636 12
    8135: 8636 13

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Le résultat de ce programme est non prévisible (bien qu'il semble que sur 2 essais, cela produise les mêmes résultats mais je me garderai bien de généraliser).

    En effet, lors du fork(), on ne sait pas quelle partie de code va obtenir la CPU : le père ou le fils et si c'est le fils, on ne sait pas s'il n'aura pas le temps de créer un petit fils avant que la main soit redonnée au père. Ce sont les joies du scheduler.

    Normallement, ce type de programme créé des fils sans arrêt puisque pour un process, il y a 2 fils créés (2 appels à la fonction g()). Tu dois avoir une limitation système ou utilisateur quelquepart qui t'empêche de créer plus de 16 process supplémentaires (je ne sais pas combien tu as de proccess running avant de lancer ton test).

    Maintenant, pourquoi "./test" fourni un nombre de lignes différents de'./test > toto". Je n'en sais rien. Peut être que dans le 1er cas, l'accès console ést bloqué par un process et que le 2eme qui essaye d'écrire se prend une erreur et n'arrive pas à écrire. Peut être aussi que dans le 2eme cas, l'écriture dans le fichier est tellement rapide qu'il n'y a plus (par hasard) de problème d'accès concurrent.

    "./test > toto" et "./test | wc -l", c'est pareil puisqu'il n'y a pas d'accès à la console.

    Amélioration du programme :
    • affichage des erreurs lors du fork(). En cas d'échec, fork() retourne -1
    • affichage des erreur dans printf(). Cette fonction retourne le nombre de caractères écrits.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Points : 42
    Points
    42
    Par défaut
    En fait, l'exercice de mon TD consistait à décortiquer la fonction.

    Mais en allant un petit peu plus loin je suis arrivé à faire ces petits tests qui m'ont supris.

    Toutefois, il y a un truc que je ne comprends pas, la correction de mon TD explique qu'il y aura toujours 9 nombres d'écrits, seul leur ordre peut changer.
    C'est donc en contradiction avec ce que tu dis, à savoir que des fils sont créés sans arrêt.

  6. #6
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    Normallement, ce type de programme créé des fils sans arrêt puisque pour un process, il y a 2 fils créés (2 appels à la fonction g()).
    Pourquoi il y aurait création de fils sans arrêt ? Suite au fork, ni le fils ni le père ne réexécute le programme depuis le début. Il se contente de poursuivre l'exécution.

    Il devrait bien y avoir, sauf erreur de calcul de ma part, 9 appels à printf().

    Maintenant pourquoi y n a-t-il plus lors de la redirection dans le fichier ? Je ne vois pas, je me demande toutefois s'il n'y a pas un souci avec les flux bufferisés, ce qui expliquerait que certaines traces, par exemple "8135: 8636 10", apparaisse à plusieurs reprises.

  7. #7
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par allezlolo Voir le message
    la correction de mon TD explique qu'il y aura toujours 9 nombres d'écrits, seul leur ordre peut changer.
    C'est donc en contradiction avec ce que tu dis, à savoir que des fils sont créés sans arrêt.
    C'est parceque j'ai dit une grosse boulette

    Il y a plusieurs ecritures que je ne comprends pas dans le fichier toto:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    8135: 8636 10
    ...
    8135: 8636 10
    ...
    8135: 8636 10
    ...
    8135: 8636 10
    Pourquoi le même process écrit 4 fois 10 alors que normallement il ne doit l'écrire qu'une seule fois (je ne remets pas en cause ce que tu as écrit dans le post)

    Citation Envoyé par gl Voir le message
    Il devrait bien y avoir, sauf erreur de calcul de ma part, 9 appels à printf().
    Je confirme les 9 écritures.

    Je sais pas pourquoi, j'avais vu un appel récursif à g() d'où mon emballement à générer une infinité de fils...
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Points : 42
    Points
    42
    Par défaut
    J'ai testé sur un autre pc avec ubuntu, cela fait exactement la même chose :o

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Peut-être est-ce parce qu'il manque les wait() sur la fin des processus fils?
    Un problème qui fermerait le fichier quand le père principal se termine...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Il se pourrait également qu'au moment du fork, le processus fils hérite d'une copie du buffer du flux de sortie du père et que quand la sortie est redirigée, tous ces buffers ne soient soldés qu'à la fermeture effective du fichier.

    Essaie de coller un fflush(NULL) juste après ton printf() et relance les tests, pour voir ...

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Points : 42
    Points
    42
    Par défaut
    là j'ai bien 9 lignes partout.

    Que dois je en conclure ?

  12. #12
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Comme le fils hérite des descripteurs du père (et donc de stdout), il y a un conflit d'accès à une ressource partagée (stdout) et c'est le système qui gère cela du moins mal qu'il peut.

    Comme ta ressource stdout n'est pas verrouillée/déverrouillée lors des accès en écritures, le comportement et le résultats est imprévisible et donc tu ne peux conclure.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  13. #13
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Citation Envoyé par allezlolo Voir le message
    là j'ai bien 9 lignes partout. Que dois je en conclure ?
    Que fopen(), fread() et leurs copines sont des fonctions gérées par une bibliothèque, donc par le processus lui-même du point de vue du système. Ces fonctions maintiennent notamment leur propre buffer, qu'elles vident occasionnellement ou sur demande (fflush()). Si ce que tu as écrit est toujours dans le tampon au moment où tu fais ton fork(), alors le processus fils hérite d'une copie de ce tampon ... avec son contenu. Au final, tu as dupliqué les infos à sortir.

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Points : 42
    Points
    42
    Par défaut
    merci à tous

Discussions similaires

  1. [Proftpd] Eclaircissement sur le fonctionnement !
    Par Mike91 dans le forum Applications et environnements graphiques
    Réponses: 0
    Dernier message: 06/02/2008, 17h41
  2. faire un test sur un programme externe
    Par marieheraud dans le forum Windows
    Réponses: 3
    Dernier message: 02/09/2004, 18h32
  3. Livre sur la programmation linux (shell et noyau)
    Par Tchetch dans le forum Linux
    Réponses: 10
    Dernier message: 07/07/2004, 08h27
  4. Questions sur la programmation Api de windows
    Par ApolloCrid dans le forum MFC
    Réponses: 7
    Dernier message: 22/02/2004, 01h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo