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 :

Programme Multi-Processus par fork()


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 302
    Par défaut Programme Multi-Processus par fork()
    Bonjour,

    Je suis en train d'essayer de paralléliser un programme qui traite séquentiellement un grand nombre de fichiers.

    Pour cela, je vais utiliser la commande fork().

    De plus, le nombre de taches tournant en même temps sera faible, en tout cas inférieur à 10.

    Dès qu'une tache se terminera, une autre sera lancée, jusqu'à traitement de tous les fichiers.

    J'ai commencé à écrire cela (cf. plus bas).
    Mais je crains plus que tout la prolifération de processus zombies.

    Quelqu'un peut-il me dire si ce code (ce n'est qu'un début) est correct ?
    Merci.

    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
     
    #define MAX_PROCESS 4
     
    /* Balayette à zombies */
    void
    sigchld_handler (int signal)
    {
        while (0 < waitpid (-1, NULL, WNOHANG))
            ;
    }
     
    /* Mise en place du gestionnaire de signaux */
    int
    install_sigaction (void)
    {
        struct sigaction sa;
     
        memset (&sa, 0, sizeof (sa));
        sa.sa_handler = sigchld_handler;
        sa.sa_flags = 0;
        sigemptyset (&(sa.sa_mask));
        if (0 != sigaction (SIGCHLD, &sa, NULL))
            return -1;
     
        return 0;
    }
     
    void
    tache_secondaire (int num)
    {
        printf ("%d:fils> Je suis le processus fils (père:%d)\n", getpid (), getppid ());
        sleep (10 * num + 5);
    }
     
    int
    main (int argc, char *argv[])
    {
        int pidfils;
        int i;
     
        /* Mise en place du gestionnaire de signaux */
        if (-1 == install_sigaction ())
        {
            fprintf (stderr, "Problème avec sigaction()\n");
            exit (EXIT_FAILURE);
        }
     
        for (i = 0; i < MAX_PROCESS; i++)
        {
            pidfils = fork ();
            switch (pidfils)
            {
                case -1:
                    fprintf (stderr, "fork() a échoué\n");
                    exit (EXIT_FAILURE);
                case 0:
                    tache_secondaire (i);
                    exit (EXIT_SUCCESS);
            }
        }
     
        /* Programme principal exécuté par le père */
        printf ("%d:pere> Je suis le processus père\n", getpid ());
     
        exit (EXIT_SUCCESS);
    }

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Ton code ne fait pas ce que tu as dit. Il créé 10 process fils puis s'arrête. Il manque la logique qui fork un nouveau fils quand un des fils s'est arrêté.

  3. #3
    Membre éclairé Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 302
    Par défaut
    Oui je sais « matafan ».

    Je n'en suis pas encore là, et je ne sais pas encore comment je vais implémenter cette mécanique

    Je veux simplement savoir si ce début de code est correct

  4. #4
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Ben oui, enfin il n'y a pas de grosse erreur qui saute aux yeux. Mais comme de toute façon ton code final n'aura rien à voir avec ça, je ne vois pas trop l'intérêt de s'étendre sur ce code. La partie délicate c'est justement le contrôle du nombre de processus.

  5. #5
    Membre éclairé Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 302
    Par défaut
    Je pensais à quelque chose comme ça :

    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
     
    #define MAX_PROCESS 4
     
    /* Balayette à zombies */
    void
    sigchld_handler (int signal)
    {
        while (0 < waitpid (-1, NULL, WNOHANG))
            ;
    }
     
    /* Mise en place du gestionnaire de signaux */
    void
    install_sigaction (void)
    {
        struct sigaction sa;
     
        memset (&sa, 0, sizeof (sa));
        sa.sa_handler = sigchld_handler;
        sa.sa_flags = 0;
        sigemptyset (&(sa.sa_mask));
        if (sigaction (SIGCHLD, &sa, NULL) != 0)
        {
            perror ("sigaction");
            exit (EXIT_FAILURE);
        }
    }
     
    void
    tache_secondaire (int num)
    {
        int delay = 10 * num + 5;
        printf ("%d:fils> Je suis le processus fils #%d (pere:%d), sleeping for %d\n", getpid (), num, getppid (), delay);
        sleep (delay);
    }
     
    int
    main (int argc, char *argv[])
    {
        int pidfils;
        int i;
        int nb_files = 13;
        int nb_tasks;
     
        /* Mise en place du gestionnaire de signaux */
        install_sigaction ();
     
        /* Boucle sur les fichiers */
        nb_tasks = 0;
        for (i = 0; i < nb_files; i++)
        {
            pidfils = fork ();
            switch (pidfils)
            {
                case -1:
                    perror ("fork");
                    exit (EXIT_FAILURE);
                case 0:
                    tache_secondaire (i);
                    exit (EXIT_SUCCESS);
            }
     
            nb_tasks++;
            if (nb_tasks > MAX_PROCESS)
            {
                waitpid (-1, NULL, WUNTRACED);
                nb_tasks--;
            }
        }
     
        /* Programme principal exécuté par le père */
        printf ("%d:pere> Je suis le processus père\n", getpid ());
     
        exit (EXIT_SUCCESS);
    }

  6. #6
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Non, ça ne marchera pas. Après avoir atteint le max de fils, le père se met en attente sur un waitpid(). Seulement quand un fils termine, tu ne sais pas si c'est le waitpid() qui va se "débloquer" en premier, ou si c'est ton signal handler qui va être appelé. Si c'est le signal handler, tu feras un waitpid() sans décrémenter nb_tasks, et tu ne forkera pas de nouveau fils.

    Tu devrais soit ne pas installer de signal handler, soit décrémenter nb_tasks dans le signal handler. Le plus simple dans ton cas étant de ne pas installer de signal handler (sinon il faut bien penser à masquer SIGCHLD dans ton signal handler, et déclarer nb_tasks en global et en volatile).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WD17] Multi-fichier par programmation
    Par v95kp5s dans le forum WinDev
    Réponses: 5
    Dernier message: 11/06/2014, 22h26
  2. Programme multi processus qui marche aléatoirement
    Par Anonymouse dans le forum Linux
    Réponses: 1
    Dernier message: 13/10/2007, 20h56
  3. Réponses: 4
    Dernier message: 30/08/2005, 12h59
  4. Programmer un automate par RS232
    Par wael khalil dans le forum Langage
    Réponses: 6
    Dernier message: 25/08/2005, 16h02
  5. Processus.. adoption d'un processus par init
    Par Francois Trazzi dans le forum Administration système
    Réponses: 15
    Dernier message: 17/01/2005, 13h56

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