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 de fork(s)


Sujet :

C

  1. #1
    Nouveau membre du Club Avatar de Butcher22
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2014
    Messages : 20
    Points : 36
    Points
    36
    Par défaut création de fork(s)
    Bonsoir,

    Il m'est demandé de créer un programme qui va créer indéfiniment des processus fils grâce à la commande fork() dans un premier temps.
    Dans un second temps, stopper ce processus de création grâce a une saisie clavier, puis attendre la fin des fils engendrés !

    Mon problème ce situe dans le fait de créer indéfiniment les fils jusqu’à la saisie clavier !

    Voici mon bout de code qui ne crée qu'un seul fils !

    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
     
    int STOP = 1;
     
    while (STOP)
    {
    	sleep(1);
    	switch (pid = fork())
    	{
    		case -1 :
    			perror("erreur fork");
    			exit(EXIT_FAILURE);
    		case 0 :
    			while (1)
    			{
    				fprintf(stdout,"(pid=%d | ppid=%d)\n",getpid(),getppid());
    				fflush(stdout);
    				sleep(5);
    			}
    			exit(EXIT_SUCCESS);
    		default :
    			if (read(STDIN_FILENO,&tmp,1))
    			{
    				fprintf(stdout,"\n== STOP ==\n");
    				STOP = 0;
    			}
    			break;		
    	}
    }
    Et un autre que je n'arrive pas à stopper !

    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
     
    int STOP = 1;
     
    while (STOP)
    {
    	sleep(1);
    	switch (pid = fork())
    	{
    		case -1 :
    			perror("erreur fork");
    			exit(EXIT_FAILURE);
    		case 0 :
    			while (1)
    			{
    				fprintf(stdout,"(pid=%d | ppid=%d)\n",getpid(),getppid());
    				fflush(stdout);
    				sleep(5);
    			}
    			exit(EXIT_SUCCESS);
    		default :
    			break;		
    	}
    }
     
    if (read(STDIN_FILENO,&tmp,1))
    {
    	fprintf(stdout,"\n== STOP ==\n");
    	STOP = 0;
    }

    Où se site le problème ?

    Merci d'avance !

  2. #2
    Membre chevronné
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Points : 1 753
    Points
    1 753
    Par défaut
    Bonsoir;
    Attention, il faut savoir que le nombre de création de processus est limité sur les systèmes UNIX ou LINUX de plus a vouloir crée des processus a l’infinie c’est effectué ou réalisé un "fork bomb" plus exactement une saturation des ressources pour aboutir à un plantage de la machine (plus simple et clair, c’est effectuer un déni de services sur un système informatique). De plus, je doute que vous puissiez créer des processus à l’infinie à cause de cette limitation qui fait également office de mécanisme de protection contre la création abusive ou accidentelle de processus par l’utilisateur (chose qui ne marche pas contre des "fork bomb" logiques, multi-utilisateurs.).
    Cependant, une question me taraude la tête; quel est le but de l’exercice . ..?
    à bientôt

  3. #3
    Nouveau membre du Club Avatar de Butcher22
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2014
    Messages : 20
    Points : 36
    Points
    36
    Par défaut
    Bonsoir

    en fait, c'est plutôt une variante , perso, d'un exo normal sur les fork qui consiste à créer N fils, puis les attendre. Tout en utilisant Kill pour les stopper dans un autre terminal.

    Sinon mon but n'est sûrement pas de saturer ma machine, quoique j'y suis arrivé, c'est pour cela que j'ai rajouter le tout premier sleep() (ligne 6), pour plus ou moins ne pas être submerger par les fork().

    Sinon pour mon cas, comment implémenter l’arrêt des fork() grâce à une saisie au clavier ?

  4. #4
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 721
    Points : 43 821
    Points
    43 821
    Par défaut
    Quand tu fais un fork(), le retour est 0 pour le pid parent (si le processus a abouti sinon -1), et le numéro de pid dans le processus enfant.
    Le fait de mettre ton read dans la partie default de ta boucle switch va déclencher la lecture dans les processus fils.

    Ensuite pour tuer les processus enfants d'un coup regardes du coté des signaux SIGKILL;SIGTERM, etc... ou la gestion des signaux USER1,USER2

    On passe normalement le pid et le signal à envoyer à celui-ci. Un pid de 0 enverra le signal à tous les process du groupe. Par contre je ne connais pas le comportement vis à vis du process envoyant : comme il fait partie du groupe, va t'il recevoir également le signal (dans ce cas, il faut gérer) ou le système ne permet pas l'envoi d'un signal à soi-même.

    Si quelqu'un le sait, ça m’intéresse.

  5. #5
    Nouveau membre du Club Avatar de Butcher22
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2014
    Messages : 20
    Points : 36
    Points
    36
    Par défaut
    Bonjour,

    Sauf erreur de ma part, fork() retourne bien un 0 pour processus fils et le pid au père, donc dans le default, et par suite les instructions effectuées dans le default sont normalement les instruction du père, elles sont équivalentes à des instructions écrites au-delà du switch, sans oublié le exit(EXIT_SUCCESS); dans le fils !

    Stopper moi si je me trompe, mon DS approche :p.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    switch (pid=fork()) 
    {
    	case -1 : /* Erreur */
    		break;
    	case 0 : /* fils */
    		exit(EXIT_SUCCESS);
    	default : /* père, qui reçoit le pid du fils */
    		break;
    }
    Sinon pour mon cas, je pense que la solution se trouve plus dans mon deuxième code, qui entre bien dans une boucle de création de fork(), mais le problème est que je n'arrive pas à reprendre la main !

    PS : Je viens de voir que mon deuxième code est mal indenté (ce qui prêterait à confusion et je m'en excuse), je règle ça......

  6. #6
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 721
    Points : 43 821
    Points
    43 821
    Par défaut
    Sauf erreur de ma part, fork() retourne bien un 0 pour processus fils et le pid au père, donc dans le default
    Oui, tu as raison, je suis mal réveillé.

    Par contre, regardes pour la gestion de signaux.

    Pour attendre la fin d'un processus : fonction wait.
    Pour envoyer un signal à un processus : fonction kill (envoie n'importe quel signal, pas que SIGKILL).

  7. #7
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Je vois trois erreurs dans la seconde implémentation que tu nous proposes :

    • les fils ne sortiront jamais de leur while (1) ;
    • le père ne sortira jamais de son while (STOP) (la lecture de l'entrée standard est réalisée hors de la boucle) ;
    • l'appel à read est, par défaut, bloquant ; donc soit le buffer d'entrée reste vide et le père est bloqué, soit il ne l'est pas et le père termine.. pas folichon.


    Note aussi qu'il est préférable de sortir d'un processus fils via _Exit plutôt qu'exit.

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Butcher22 Voir le message
    Bonjour,

    Sauf erreur de ma part, fork() retourne bien un 0 pour processus fils et le pid au père, donc dans le default, et par suite les instructions effectuées dans le default sont normalement les instruction du père, elles sont équivalentes à des instructions écrites au-delà du switch, sans oublié le exit(EXIT_SUCCESS); dans le fils !

    Stopper moi si je me trompe, mon DS approche :p.
    Bonjour

    C'est exact (à condition que le fils fasse un exit() sinon tout ce qui est en dehors du switch() sera exécuté à la fois par le père et à la fois par le fils).

    Citation Envoyé par Butcher22 Voir le message
    Sinon pour mon cas, je pense que la solution se trouve plus dans mon deuxième code, qui entre bien dans une boucle de création de fork(), mais le problème est que je n'arrive pas à reprendre la main !
    Il faudrait que tes fils fassent des sleep() dans la boucle pour que le père puisse reprendre la main. Surtout si tu lances "n" fils (même en parallèle il n'y a qu'une machine physique pour supporter tout ça !!!)
    Ensuite, dans ton père, tu fais une bête saisie (par exemple du pid à tuer) et si ce pid existe (il serait alors bon que le père stocke les pid générés dans un tableau) tu lui envoies un kill(SIGTERM, pid)...

Discussions similaires

  1. création de n processus fils avec fork
    Par TuxThePenguin dans le forum C
    Réponses: 2
    Dernier message: 02/10/2015, 00h39
  2. création processus fork unix
    Par jojo_ol76 dans le forum POSIX
    Réponses: 2
    Dernier message: 15/12/2009, 15h28
  3. fork & création de processus
    Par seb__ dans le forum POSIX
    Réponses: 3
    Dernier message: 08/10/2006, 23h42
  4. Création image BMP
    Par Anonymous dans le forum C
    Réponses: 2
    Dernier message: 25/04/2002, 16h04

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