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

Linux Discussion :

[C] Création de processus


Sujet :

Linux

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 73
    Points : 44
    Points
    44
    Par défaut [C] Création de processus
    Bonjour,

    Je voudrais que vous m'aidez d'écrire un Programme en C qui crée 4 fils F1,F2,F3 et F4. chaque fils a le même code (fonction void fils(...)) qui permet, entre autre, d’afficher le numéro du fils (1 a 4) ainsi que son PID. Le père affiche, quant a lui, un simple message a chaque création de fils puis un dernier message avant de terminer.

    1 ) Peut-on passer en paramètre la fonction fils le PID du fils ? Ecrire ce programme en le généralisant à n processus.

    2 ) Nous désirons ajouter dans la fonction fils une attente aléatoire de 1 à 10 secondes différente pour chacun des fils. Le fils indiquera le temps pendant lequel il va s’endormir et affichera un message lors de son réveil. Pour rappel, le code suivant permet d’initialiser le générateur de nombres aléatoires grâce à la commande time et d'endormir le programme pendant un temps aléatoire :
    double attente;
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    time_t t;
    time(&t);
    srand(t);
    attente = rand() * 10.0 / RAND_MAX;
    sleep(attente);

    voila mon code :
    Code C : 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
    17
    18
    19
    20
    21
    22
    23
    24
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<sys/types.h>
     
    void fils(int);
    int main ()
    {
     
    int i;
    for (i=1; i<=4; i++) {
    if(fork()== 0) {
    printf ("creation du fils: ", i);
    fils(i);
    exit(0);
    }
    }
    printf ("Voila un dernier message \n" );
    return (0);
    }
    void fils (int i) {
    printf ("je suis le Fils nimero: %i mon PID est : %i \n", i, getpid());
    exit(0);
    }


    Cordialement

  2. #2
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Ce code doit faire ce que tu demandes néanmoins, pour je ne sais quel raison, rand() renvoi systématiquement la même valeur, est ce ma bécane qui déconne?

    Code C : 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <time.h>
    #define N 4
     
    static void fils (unsigned, long);
     
    int main (void)
    {    
        for (unsigned i = 1; i <= N; i++) 
        {
            long pid;
            switch (pid = fork())
            {
                case -1 : perror ("erreur creation du fils"); break;
                case  0 : fils (i, getpid()); return EXIT_SUCCESS;
                default : printf("PERE creation FILS n°%u / pid : %ld\n", 
                          i, pid); break;
            }
        }
        puts ("Voila un dernier message du pere");    
        return EXIT_SUCCESS;
    }
     
    static void fils (unsigned i, long pid) 
    { 
        srand ((unsigned)time (NULL));
        int attente = rand () * 10.0 / RAND_MAX;
        printf ("FILS n°%u / pid : %ld / ppid : %ld\n",
                i, pid, (long)getppid());
        printf ("FILS n°%u va s'endormir pdt %d sec\n", i, attente);
        sleep ((unsigned)attente);
        printf ("FILS n°%u se reveille\n", i);
    }

  3. #3
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    telle qu'ecrite, la division est entiere.....

  4. #4
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Oui mais je ne vois pas pourquoi ça me sort le même nombre pour les 4 tirages?
    Une idée souviron34?

  5. #5
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    et c'est quoi ce nombre ??

  6. #6
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Le nombre est aléatoire, à chaque lancement de programme, mais est le même dans les N processus créés.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 40
    Points : 28
    Points
    28
    Par défaut
    J'espère que j'ai pas zappé des réponses. Mais pourquoi passer le PID en paramètre de la fonction fils ? Un simple appel à gedpid dans chaque processus fils et le tour est joué.

  8. #8
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par AureK Voir le message
    Mais pourquoi passer le PID en paramètre de la fonction fils ? Un simple appel à getpid() dans chaque processus fils et le tour est joué.
    Si la question est pour moi, je répondrais simplement que c'est ce que voulait le PO.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 40
    Points : 28
    Points
    28
    Par défaut
    Non non ! Ma question était simplement pour savoir pourquoi le choix de passer le PID en paramètre alors qu'il peut se retrouver simplement par l'appel à la fonction getpid.

    Si l'exercice est ainsi fait, je comprends tout à fait. Si tel n'est pas le cas pourquoi ne pas utiliser cette méthode.

    Et, tu réponds très bien à la question du PO.

  10. #10
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Le nombre est aléatoire, à chaque lancement de programme, mais est le même dans les N processus créés.
    OK c'est normal (voir la discussion sur le forum C Probleme avec fork).

    Lors d'un fork, le syseme duplique l'etat de la memoire , donc le time et le srand devraient etre les memes....

  11. #11
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Lors d'un fork, le syseme duplique l'etat de la memoire , donc le time et le srand devraient etre les memes....
    ça je le savais déjà et c'est bien pour ça que je fais le srand() après le fork() alors comment expliquer ça?

  12. #12
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Ok finalement; j'ai compris ce qui n'allait pas, time() renvoi le temps actuel avec une précision à la seconde donc évidemment tous les processus se retrouvaient dans la même seconde. Pour contourner çà, j'utilise pour l'instant une astuce non portable, limité au système UNIX : le temps retourné est un "long" représentant le nombre de seconde depuis Epoch. Donc j'ajoute à ce nombre le numéro du fils et voilà le travail.

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <time.h>
    #define N 4
     
    static void fils (unsigned, long);
     
    int main (void)
    {    
        for (unsigned i = 1; i <= N; i++) 
        {
            long pid;
            switch (pid = fork())
            {
                case -1 : perror ("erreur creation du fils"); break;
                case  0 : fils (i, getpid()); return EXIT_SUCCESS;
                default : printf("PERE creation FILS n°%u / pid : %ld\n", 
                          i, pid); break;
            }
        }
        puts ("Voila un dernier message du pere");    
        return EXIT_SUCCESS;
    }
     
    static void fils (unsigned i, long pid) 
    { 
        srand ((unsigned)time (NULL) + i);
        int attente = rand () * 10.0 / RAND_MAX;
        printf ("FILS n°%u / pid : %ld / ppid : %ld\n",
                i, pid, (long)getppid());
        printf ("FILS n°%u va s'endormir pdt %d sec\n", i, attente);
        sleep ((unsigned)attente);
        printf ("FILS n°%u se reveille\n", i);
    }
    Bien entendu, si quelqu'un voit un moyen de le faire proprement de manière portable, je suis preneur.

  13. #13
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    telle qu'ecrite, la division est entiere.....
    Quelle division?

  14. #14
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Ok finalement; j'ai compris ce qui n'allait pas, time() renvoi le temps actuel avec une précision à la seconde donc évidemment tous les processus se retrouvaient dans la même seconde. Pour contourner çà, j'utilise pour l'instant une astuce non portable, limité au système UNIX : le temps retourné est un "long" représentant le nombre de seconde depuis Epoch. Donc j'ajoute à ce nombre le numéro du fils et voilà le travail.
    Surtout c'est une astuce qui ne marche pas (ou par accident) : la plupart du temps, les PID sont affectés séquentiellement, et les secondes depuis "Epoch" aussi...

    Citation Envoyé par nicolas.sitbon Voir le message
    Bien entendu, si quelqu'un voit un moyen de le faire proprement de manière portable, je suis preneur.
    Tout simplement : pour chaque fils, le père passe le résultat de rand() au fils qui s'en sert comme argument de srand.

  15. #15
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par corrector Voir le message
    Surtout c'est une astuce qui ne marche pas (ou par accident) : la plupart du temps, les PID sont affectés séquentiellement, et les secondes depuis "Epoch" aussi...
    Quel est le rapport avec le PID? en quoi l'astuce ne marche pas?

  16. #16
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Quel est le rapport avec le PID? en quoi l'astuce ne marche pas?
    Si j'ai bien compris, tu additionnes le PID et le temps en secondes, pour obtenir un nombre unique.

    Hors, deux processus créés successivement ont des PID différents de 1 (sauf sous les OS "sécurisés"), et l'heure en seconde peut être différente de 1 pour deux processus qui lisent l'heure successivement, ce qui ne veut pas dire qu'il y a une seconde d'intervalle entre les deux, juste qu'ils ne lisent pas l'heure dans la même seconde.

    Donc, selon l'ordre dans lequel les fils démarrent effectivement, il est tout à fait possible, même parfaitement vraisemblable, qu'ils génèrent la même graine.

  17. #17
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par corrector Voir le message
    Si j'ai bien compris, tu additionnes le PID et le temps en secondes, pour obtenir un nombre unique.
    Ok c'est bien ce que je pensais, tu n'as même pas pris la peine de lire le code que j'ai posté...
    Bref pour m'en convaincre, j'ai lancé le processus avec différente valeur pour N variant de 2 à 100 et n'ai pas obtenu 2 fois la même graine, car même à 100 processus lancés, le temps n'excède pas la seconde donc même si on est à cheval entre 2, le numéro de processus augmentant de 1 en 1, je n'ai aucune chance d'avoir la même graine. Après il faudrait pousser les tests mais disons que dans ce cas l'astuce à l'air de bien fonctionner.
    Par ailleurs je n'ai pas dis que c'était LA solution, j'en ai proposé une rapide qui donne des résultats un peu près convenable en rapport à ce que demandait le PO. Tu aurais pu au moins lire le code, faire les tests et répondre quelque chose de constructif voir même proposer une solution/un exemple, d'autant que ça n'est pas une application critique, je dirais qu'on se moque que ça soit du pseudo aléatoire grossier...

  18. #18
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Ok c'est bien ce que je pensais, tu n'as même pas pris la peine de lire le code que j'ai posté...
    Ben si figures-toi.

    Seulement,
    • je l'ai lu en diagonal,
    • au moment de rédiger la réponse, il m'était sorti de l'esprit
    alors je me suis basé uniquement sur la description textuelle pour répondre, et j'ai cru que "le numéro du fils" = PID.

    Ce qui est quasiment le cas, et ne change absolument rien à mon analyse, sauf évidement que le coup de "la plupart du temps, les PID sont affectés séquentiellement", et "deux processus créés successivement ont des PID différents de 1 (sauf sous les OS sécurisés)" deviennent : par définitions, les processus sont numérotés séquentiellement.

    Bon, en dehors de ce détail, que dis-tu de mon explication?

    L'as-tu lue?

    Citation Envoyé par nicolas.sitbon Voir le message
    Bref pour m'en convaincre, j'ai lancé le processus avec différente valeur pour N variant de 2 à 100 et n'ai pas obtenu 2 fois la même graine, car même à 100 processus lancés, le temps n'excède pas la seconde donc même si on est à cheval entre 2, le numéro de processus augmentant de 1 en 1, je n'ai aucune chance d'avoir la même graine. Après il faudrait pousser les tests mais disons que dans ce cas l'astuce à l'air de bien fonctionner.
    Par ailleurs je n'ai pas dis que c'était LA solution, j'en ai proposé une rapide qui donne des résultats un peu près convenable en rapport à ce que demandait le PO.
    Je ne considère pas que qu'une solution qui fonctionne aléatoirement soit convenable.

    Citation Envoyé par nicolas.sitbon Voir le message
    Tu aurais pu au moins lire le code,
    Tu aurais pu essayer de comprendre ce que j'expliquais (et voir que c'était à 99.9% applicable), même si j'ai mal lu ton message, plutôt que seulement me faire des reproches.

    Citation Envoyé par nicolas.sitbon Voir le message
    faire les tests
    Il est inutile de faire des tests pour voir une erreur de conception.

    Citation Envoyé par nicolas.sitbon Voir le message
    et répondre quelque chose de constructif voir même proposer une solution/un exemple,
    Si tu ne lis pas mes messages, ça ne m'incite vraiment pas à répondre "quelque chose de constructif".

    Citation Envoyé par nicolas.sitbon Voir le message
    d'autant que ça n'est pas une application critique, je dirais qu'on se moque que ça soit du pseudo aléatoire grossier...
    "Aléatoire grossier", le fait de sortir exactement la même suite de nombres dans plusieurs processus, c'est une litote.

    Si on se moque du que ce soit du pseudo-aléatoire grossier, pourquoi pas une suite arithmétique, voir même une constante?

  19. #19
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par corrector Voir le message
    Donc, selon l'ordre dans lequel les fils démarrent effectivement, il est tout à fait possible, même parfaitement vraisemblable, qu'ils génèrent la même graine.
    Pourquoi ne génèrent ils pas la même graine? je n'arrive pas à reproduire le comportement que tu cites.
    Encore une fois je le dis, le but pour moi était simplement de fournir des graines différente et jusqu'à ce que tu me prouves le contraire c'est bien ce qui se produit.

Discussions similaires

  1. Réponses: 6
    Dernier message: 05/11/2014, 11h24
  2. problème de création de processus
    Par nedoura20doudi dans le forum Débuter
    Réponses: 1
    Dernier message: 28/11/2009, 17h08
  3. Echec lors de la création du processus pour initdb
    Par madfu dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 02/04/2008, 18h52
  4. Réponses: 6
    Dernier message: 20/12/2006, 09h55
  5. fork & création de processus
    Par seb__ dans le forum POSIX
    Réponses: 3
    Dernier message: 09/10/2006, 00h42

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