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 :

Création d'un anneau de n processus


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 8
    Points : 8
    Points
    8
    Par défaut Création d'un anneau de n processus
    Bonjour, je bloque depuis plus d'une semaine sur un TP, le prof ne donne pas de correction et j'aurai grandement besoin de le réussir pour réviser en vue du test. La consigne est simple : réaliser un anneau de n processus (passé par argv[1]) qui donnent leur pid au processus suivant.
    J'en suis rendu à avoir une file de processus qui transmettent leur pid au suivant mais le processus n ne peut pas transmettre au processus 1.
    Je vois bien que mon code ne permet pas aux processus de former une boucle mais je n'arrive pas à comprendre comment le transformer pour y parvenir.

    Voici le code en question :

    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
    //écrire la mise en place de l'anneau de n proc
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<sys/wait.h>
     
    int main (int argc, char* argv[])
    {
    	if(argc != 2)
    	{
    		printf("Nombre d'arguments incorrect\n");
    		exit(1);
    	}
    	int out, in, i, k;
    	int n = atoi(argv[1]);
    	int* t = (int*)malloc(2*n*sizeof(int));
    	//0 : out; 1 : in
    	for(i = 0; i<n; i++)
    	{
    		pipe(&t[2*i]); 	 	 
    		if(fork()==0)
    		{
     
    			printf("processus : %d\n", i+1);
     
    			//fermeture
    			for(k = 0; k<2*n; k++)
    			{
    				if(k != 2*i+1 && k != 2*i-2) // si k : out ET pas out du precedent
    				{
    					if((i == 0 && k != 2*n-1) || i != 0) // proc 0 : ne ferme pas le in du dernier proc
    					{	
    						//printf("fermeture processus : %d\n", k);									
    						close(t[k]);
    					}	
    				}
    			}
     
    			//transfert des ids
    			in = getpid();	
    			write(t[2*i+1], &in, 4);
    			read(t[2*i-2], &out, 4);
     
    			printf("In : %d\n", in);
    			printf("Out : %d\n", out);
     
    			exit(0);
    		}
    		wait(NULL);
    	}
    	free(t);
    	exit(0);
    }
    Merci de votre aide

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    Reprend ton post et mets le code sous balise (le bouton #) sinon c'est illisible.

    Quand on fait un fork(), il est facile de connaître le pid du fils c'est la valeur retournée au fork() du père.
    Pour que le fils trouve celui du père, c'est plus compliqué on peut utiliser un pipe.
    Le père connait le pid de son père, il peut donc le transmettre et on peut utiliser un autre pipe par lequel on recevra le pid du grand-père pour le transmettre à son fils. Le dernier des fils n'aura qu'à le lire.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    En fait le problème ça serait de faire en sorte que le processus n attende que le processus n-1 ai écrit son pid dans le pipe pour le lire. Je pensais à utiliser un wait sauf dans le processus 0 mais ça ne fonctionne pas.

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    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 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Bonjour,

    En fait, il y a plusieurs petits problèmes de conception dans ton programme, et la plupart d'entre eux sont structurels, notamment au fait que ce type de communication peut engendrer des deadlocks, et que la fin de tes processus est mal contrôlée : un processus fils qui meurt trop tôt envoie un signal qui reste en attente, certes, mais si un processus père veut lui écrire, cela provoquera un SIGPIPE. Un processus père qui meurt trop tôt, lui, peut provoquer la fin de sa descendance, même si en principe celle-ci se retrouve attachée à init. À part cela :

    • Lignes 32 à 35, ta clause i != 0 empêche le processus de fermer tout descripteur, quel qu'il soit. Et cela concerne non pas le père original, mais le premier des fils ;
    • Lignes 42 et 43, tu as écrit write(&in) et read(&out) ;
    • Ligne 18, c'est « 0: in ; 1: out » et pas l'inverse. Passe ton programme en revue pour voir si les index de ton tableau sont toujours les bons ;
    • C'eût été beaucoup plus simple de créer récursivement des fils en cascade qui créent à chaque fois leur propre tube, mais du côté de l'arborescence des processus, il est vrai qu'il est préférable de tous les avoir au même niveau ;


    Ce qu'il faut faire, donc, c'est créer un tube si l'on n'est pas le dernier processus OU utiliser t[1] et t[2*i-1] si on l'est.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Je ne comprend pas grand chose à ce que je doit faire algorithmiquement parlant. (notre prof nous a rapidement balancé les fonctions pipe(), close() et fork() et on devait en faire un anneau c'est un peu léger ^^') Le processus 0 se fermera toujours avant que le processus n écrive son pid et donc il ne pourra jamais le récupérer. J'avais essayé avec un tableau 2D, chaque fils créant un tube dans t[i] mais j'arrivais au même résultat.

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    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 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par ludocorpe Voir le message
    Le processus 0 se fermera toujours avant que le processus n écrive son pid et donc il ne pourra jamais le récupérer.
    Tout le problème est là. :-) C'est donc une question de conception initiale. Il ne faut donc PAS que les processus se terminent.

    Pour cela, tu fais une boucle infinie donc tu ne sors que lorsqu'un critère donné est rempli : réception d'un signal, frappe au clavier, délai de grâce déterminé en entrant dans ton programme, ou n'importe quoi d'autre. Tu peux aussi utiliser tes tubes pour faire circuler autre chose qu'un PID. Tu peux décider par exemple que l'envoi de la valeur « -1 » doit être interprété comme l'ordre de faire suivre cette valeur dans le tube puis de sortir immédiatement, de façon à provoquer la fin en cascade de tous les processus de l'anneau.

    Mais si tu n'as pas envie de t'ennuyer avec tout cela maintenant, tu peux te contenter d'ajouter alarm(30); juste après fork() dans ton programme. Cela initialisera un timer à 30 secondes, timer qui enverra le signal SIGALRM à l'échéance. Et comme ton programme n'est pas prévu pour les récupérer, ledit signal provoquera par défaut la fin du processus.

    Je ne comprend pas grand chose à ce que je doit faire algorithmiquement parlant. (notre prof nous a rapidement balancé les fonctions pipe(), close() et fork() et on devait en faire un anneau c'est un peu léger ^^')
    Un pipe est une ressource système indépendante du processus qui l'a engendré et/ou de ceux qui l'utilisent. Le tube lui-même est géré par le noyau et est « en dehors » du périmètre de tout processus puisqu'il sert justement à établir une relation entre plusieurs d'entre eux. C'est également un canal de communication unidirectionnel. Quand tu appelles pipe, tu obtiens une paire de descripteurs de fichiers qui correspondent respectivement à l'entrée et à la sortie du tube. Et comme tous les descripteurs de fichiers (qu'ils servent à ouvrir des fichiers ordinaires, des tubes nommés ou des sockets), ils sont hérités par les processus fils lors d'un fork s'ils ne sont pas refermés auparavant.

    Ça veut dire que, dans l'absolu, rien n'empêche un processus de s'écrire à lui-même en écrivant par un bout et en lisant par l'autre puisqu'il dispose des deux descripteurs. Ça signifie également que tu pourrais avoir une dizaine de processus écrivant dans le même tube et une dizaine d'autres lisant le même également. Du côté des rédacteurs, tout ce qui est écrit avec write() est envoyé à la queue-leu-leu dans le tube et, du côté des lecteurs, c'est le premier processus réveillé par l'ordonnanceur et qui est bloqué sur read() qui récupère ce qui s'y trouve, dans la limite de la quantité précisée par le paramètre count. S'il n'y a pas autant de données dans le tube, l'appel système se termine quand même et read() renvoie le nombre de caractère qu'il a pu lire. Évidemment, ce n'est pas ce qu'on a l'intention de faire ici.

    Ce n'était pas une mauvaise idée de créer en une fois autant de tubes que de processus. Et utiliser un tableau à deux dimensions était même une très bonne idée. Les seules choses qu'il faut retenir est qu'un tube doit se trouver « entre » deux processus, et qu'il doit y avoir un relation de congruence, comme un modulo, quand tu arrives au bout de la liste. Par exemple, pour dix processus et dix tubes, chacun numérotés de 0 à 9 :

    • le tube numéro 0 doit être partagé entre le processus 0 et le processus 1 ;
    • le tube numéro 1 doit être partagé entre le processus 1 et le processus 2 ;
    • le tube numéro 2 doit être partagé entre le processus 2 et le processus 3 ;
    • le tube numéro 9 doit être partagé entre le processus 9 et le processus 0.


    Ça veut dire que juste après ton fork, là où tu as écrit "processus : %d", tu simplement dois contrôler si le processus en question est ou non le dernier de la liste. En fonction de cela, soit tu récupères normalement ton descripteur, soit tu utilises celui du début de liste, tout simplement. Et tu fermes les autres ensuite. Tu peux même faire cela en une seule clause en utilisant judicieusement l'opérateur modulo « % ».

    Tu peux rendre ton programme plus clair en déclarant d'emblée deux variables p_in et p_out auxquelles tu assigneras dès le départ les bons descripteurs, puisés aux bons endroits dans ton tableau et ne plus avoir à faire le calcul par la suite dans ton code.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    J'ai repris mon code depuis zéro avec un tableau 2D je parviens à faire une chaîne si je force chaque processus à attendre la fin du précédent avec un wait(NULL) le problème c'est qu'ils s’exécutent chacun leur tour au lieu de le faire en même temps.

    Je pense pourtant avoir compris la structure du programme que je dois réaliser :
    • Déclaration des variables / tableau de tubes
    • boucle de 1 à n
    • pipe(t(i+1);
    • fork()
      • fermeture des tubes inutiles
      • boucle infinie et alarm(10)
        • écriture dans le tube à destination du processus suivant (sauf si on est le dernier processus dans ce cas on écrit dans 0)
        • lecture de son tube pour connaitre le pid precedent


    voici le code que 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
    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
    81
    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<sys/wait.h>
     
    int main(int argc, char* argv[])
    {
    	if(argc != 2)
    	{
    		printf("Nombre d'arguments incorrect\n");
    		exit(1);
    	}
     
    	int n = atoi(argv[1]);
    	int ** t = (int**)malloc(n*sizeof(int*));
    	int i, j, pidPrec, pid;
    	int in = 1, out = 0;
    	for(i = 0; i < n; i++)
    		t[i] = (int*)malloc(2*sizeof(int));
     
    	for(i = 0; i<n; i++)
    	{
    		if(i == n-1)
    			pipe(t[0]);
    		else
    			pipe(t[i+1]);
     
    		if(fork() == 0)
    		{
     
    			printf("P %d\n", i);
    			//fermeture
    			if(i == n-1)
    			{		
    				for(j = 0; j < n; j++)
    				{		
    					if(j == i)
    						close(t[i][in]);
    					else if(j == 0)
    						close(t[0][out]);
    					else
    					{
    						close(t[j][out]);
    						close(t[j][in]);
    					}		
    				}
    			}
    			else
    			{
    				for(j = 0; j < n; j++)
    				{		
    					if(j == i)
    						close(t[i][in]);
    					else if(j == i+1)
    						close(t[i+1][out]);
    					else
    					{
    						close(t[j][out]);
    						close(t[j][in]);
    					}
    				}		
    			}
    			alarm(10);
    			while(1)
    			{
    				//transfert des ids
    				pid = getpid();	
    				if(i != n-1)
    					write(t[i + 1][in], &pid, 4);
    				else
    					write(t[0][1], &pid, 4);
    				read(t[i][out], &pidPrec, 4);
    				printf("P%d pid : %d\n",i, pid);
    				printf("P%d pidPrec : %d\n",i, pidPrec);
    			}
    		}
    		//wait(NULL);	
    	}	
    	free(t);
    	exit(0);
    }
    Malheureusement sans le wait je n'ai simplement plus d'affichage et en mettant out à 1 et in à 0 les processus s'affichent en boucle mais ils ne récupèrent plus le pid précédent

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    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 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Quelques remarques :

    • En C, contrairement aux apparences (et à certaines idées fausses bien ancrées), un tableau multidimensionnel n'est pas un « tableau de tableaux ». Et plus précisément, tu n'es pas obligé de faire des malloc() en cascade pour les déclarer. Un tableau est une suite consécutive d'octets en mémoire, même à plusieurs dimensions. Dans ce dernier cas, le compilateur fait exactement ce que tu faisais toi-même avec ton tableau à une seule dimension : il multiplie les indices pour retrouver l'index exact.
    • Un tableau n'est pas un pointeur. Là encore, c'est le langage C qui résout le nom du tableau (seul) en son adresse en mémoire pour pouvoir ensuite l'indexer comme un pointeur, mais c'est purement symbolique. Il n'y a pas de déclaration de variable supplémentaires en mémoire autre que les « cases » du tableau ;
    • Tu n'es pas obligé non plus de passer par malloc() : en règle générale, on économise la pile mais s'il s'agit uniquement de déclarer n paires de descripteurs et que n reste raisonnable (disons de 1 à 50), tu peux tout-à-fait passer par une variable locale. La seule chose est que la taille du tableau ne serait alors pas connue à l'avance mais le C99 sait très bien gérer cela à l'aide des VLA.
    • Tes grandes lignes sont presque les bonnes mais il ne faut pas faire le test entre le premier processus et les autres à chaque condition. Comme on l'a dit plus haut, il faut déterminer une fois pour toutes les descripteurs à utiliser en début de programme, et s'appuyer sur eux ;
    • Tu as oublié de mettre un break dans le corps de ton if (fork()). Du coup, tes processus fils vont se mettre à créer eux-mêmes des petits fils surnuméraires, qui eux-mêmes vont en créer d'autres jusqu'à ce que la boucle atteigne son terme. Si atoi(argv) est suffisamment élevé, ton programme va devenir une fork bomb.


    Malheureusement sans le wait je n'ai simplement plus d'affichage et en mettant out à 1 et in à 0 les processus s'affichent en boucle mais ils ne récupèrent plus le pid précédent
    C'est normal : leur processus père prend fin immédiatement et tous les processus fils sont rattachés à init. Normalement, ils devraient toujours avoir accès à leur console mais s'ils changent de session à cause de cela ou qu'ils passent en arrière-plan et que cela gène leur entrée standard, il est possible que cela les empêche de communiquer, voire provoque leur fin.

    N'oublie pas, enfin, de mettre des commentaires dans ton programme. Pas à chaque ligne, mais en introduction de chaque grand « paragraphe » pour expliquer sommairement ce que tu fais et pourquoi tu as fait certains choix. Cela facilitera non seulement la tâche de ton professeur, mais aussi la tienne quand tu reliras ton programme dans quelques semaines (tu verras à quel point il est étonnant de ne plus être capable de relire ce qu'on a soi-même écrit).

    À part cela, j'avais mal lu l'énoncé : je pensais qu'on devait introduire un jeton dans l'anneau et que les processus se le passaient à tour de rôle mais, en réalité, il s'agit simplement de passer son PID à son voisin et, dans ce cas, on n'est pas obligé de maintenir en vie son programme, à condition quand même d'écrire d'abord son PID puis d'utiliser le read comme appel bloquant. C'est bien ce que tu fais, mais cela peut conduire à un deadlock : le write aussi serait bloquant si personne n'était derrière pour le lire en premier lieu. Heureusement, ce problème est automatiquement résolu par le fait que les pipes comportent un buffer minimum (typiquement 4 Kio) qui peut largement absorber la taille d'un PID.

    Par contre, il y a quelque chose dont il faut tenir compte : le SIGPIPE. Si un tube est refermé par le lecteur et que le rédacteur tente ensuite d'y écrire, alors celui-ci recevra un signal pour tube brisé, qui provoquera sa fin. Cela va être vrai a fortiori si le lecteur meurt prématurément.

    Comme, globalement, ton approche est la bonne et que tu as fait l'effort de produire deux programmes complets et compilant correctement (avec les balises), je te propose ma version de l'exercice :

    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
    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
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    /*
     * anneau.c - Lundi 5 décembre 2016
     * Obsidian, pour developpez.net
     */
     
    #define _XOPEN_SOURCE 500
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
     
     
    #define MIN_PROC 2      // Nombre minimum de processus
    #define MAX_PROC 20     // Nombre maximum de processus
     
    int main (int argc,char ** argv)
    {
        int n;  // Nombre de processus dans l'anneau
     
        /* Lecture du paramètre */
        if (argc<2 || (n = (int)strtol(argv[1],NULL,0))<MIN_PROC || n>MAX_PROC)
        {
            fprintf (stderr,"Usage : %s <nombre>\n"
                            "Avec <nombre> compris entre %d et %d.\n",
                            argv[0],MIN_PROC,MAX_PROC);
            exit(1);
        }
        else
        {
            pid_t   pid;        // Réception du PID lors de fork()
            int     p[n][2];    // Place pour n paires de descripteurs (VLA)
            int     i;          // Indice de boucle
     
            /* Indication du nombre de processus à engendrer */
            printf ("Nombre de processus à engendrer : %d\n",n);
     
            /* Création des n tubes anonymes.             */
            /* On considère que l'appel réussit toujours. */
            for (i=0;i<n;++i) pipe(p[i]);
     
            /* Génération des n processus fils, qui vont communiquer */
            /* entre eux. Le processus père reste en superviseur.    */
            for (i=0;i<n;++i)
            {
                pid = fork();
     
                if (pid>0)
                {
                    printf ("Création du processus fils #%d : PID %d\n",i,pid);
                }
                else if (!pid)
                {
                    /*                          */
                    /* ---- Processus fils ---- */
                    /*                          */
     
                    int     in;     /* Descripteur d'entrée     */
                    int     out;    /* Descripteur de sortie    */
                    int     data;   /* Donnée à émettre         */
     
                    int     j;      /* Autre indice de boucle (puisque i reste */
                                    /* de fait notre numéro de processus fils. */
     
                    /* Temporisation pour que la boucle du processus père ait   */
                    /* le temps de se terminer avant de commencer le traitement */
                    sleep(1);
     
                    /* Récupération des descripteurs adéquats */
                    in  = p[ i       ][0];
                    out = p[(i+1) % n][1];
     
                    /* Fermeture des descripteurs inutiles */
                    for (j=0;j<n;++j)
                    {
                        if (p[j][0] != in)  close(p[j][0]);
                        if (p[j][1] != out) close(p[j][1]);
                    }
     
                    /* Récupération et émission de notre PID */
                    data = (int)getpid();
                    printf ("Processus #%d : émission de %d\n",i,data);
                    write (out,&data,sizeof data);
                    close (out);
     
                    /* Réception de la donnée de l'autre processus */
                    data = (int)getpid();
                    read (in,&data,sizeof data);
                    printf ("Processus #%d : réception de %d\n",i,data);
                    close (in);
     
                    /* En fin de traitement, un break pour quitter la boucle */
                    /* démarrée par le processus père.                       */
                    break;
                }
                else perror ("Erreur à l'appel de fork()");
            }
     
            /* Si PID est non nul à l'issue de la boucle, c'est qu'on est  */
            /* toujours dans le processus père. On en profite pour faire n */
            /* wait() successifs pour attendre tous nos fils.              */
            if (pid>0)
            for (i=0;i<n;++i) wait(NULL);
        }
     
        return 0;
    }

    $ ./anneau 10
    Nombre de processus à engendrer : 10
    Création du processus fils #0 : PID 11840
    Création du processus fils #1 : PID 11841
    Création du processus fils #2 : PID 11842
    Création du processus fils #3 : PID 11843
    Création du processus fils #4 : PID 11844
    Création du processus fils #5 : PID 11845
    Création du processus fils #6 : PID 11846
    Création du processus fils #7 : PID 11847
    Création du processus fils #8 : PID 11848
    Création du processus fils #9 : PID 11849
    Processus #1 : émission de 11841
    Processus #0 : émission de 11840
    Processus #1 : réception de 11840
    Processus #2 : émission de 11842
    Processus #2 : réception de 11841
    Processus #4 : émission de 11844
    Processus #3 : émission de 11843
    Processus #4 : réception de 11843
    Processus #6 : émission de 11846
    Processus #7 : émission de 11847
    Processus #3 : réception de 11842
    Processus #7 : réception de 11846
    Processus #5 : émission de 11845
    Processus #5 : réception de 11844
    Processus #6 : réception de 11845
    Processus #8 : émission de 11848
    Processus #8 : réception de 11847
    Processus #9 : émission de 11849
    Processus #9 : réception de 11848
    Processus #0 : réception de 11849
    Interdiction absolue de pomper ce programme et le rendre à ton professeur, naturellement. Par contre, tu peux pleinement t'en inspirer pour écrire le tien.

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Merci j'ai réussi à mieux comprendre comment tout s'agençait et mettre en forme un programme qui fonctionne pas mal
    (De toutes façons ce code n'était que la première partie d'un exercice qui n'a pas pour but d'être rendu c'est simplement de la préparation aux examens ^^)

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    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 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par ludocorpe Voir le message
    Merci j'ai réussi à mieux comprendre comment tout s'agençait et mettre en forme un programme qui fonctionne pas mal
    (De toutes façons ce code n'était que la première partie d'un exercice qui n'a pas pour but d'être rendu c'est simplement de la préparation aux examens ^^)
    Dans ce cas, n'hésite pas à le partager ici également, qu'on puisse le commenter à son tour.
    Histoire qu'on en profite pour éviter certains autres pièges sournois dans lesquels tu pourrais tomber en essayant d'en éviter d'autres…

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

Discussions similaires

  1. création d'une liste chainé de processus
    Par katiii dans le forum Général Java
    Réponses: 5
    Dernier message: 07/12/2007, 10h45
  2. création de plusieurs processus
    Par Paul75 dans le forum Linux
    Réponses: 5
    Dernier message: 29/01/2007, 11h22
  3. Réponses: 6
    Dernier message: 20/12/2006, 08h55
  4. fork & création de processus
    Par seb__ dans le forum POSIX
    Réponses: 3
    Dernier message: 08/10/2006, 23h42
  5. Problème création et destruction de processus.
    Par loupdeau dans le forum MFC
    Réponses: 5
    Dernier message: 08/04/2005, 13h33

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