Gestion des processus Unix

Résolu
don8 Messages postés 12 Date d'inscription   Statut Membre Dernière intervention   -  
 indigène_du_net -
Bonjour à tous,
J'aimerai savoir s'il y a moyen de créer un arbre filiforme des processus, en demandant à l'utilisateur le nombre de processus descendant du père. Par exemple, si ce nombre vaut 2, le père aura un fils et un petit fils; si c'est 3, alors le père aura un fils, un petit-fils et le fils de son petit-fils.

Merci
A voir également:

2 réponses

sambia39 Messages postés 610 Date d'inscription   Statut Membre Dernière intervention   49
 
Bonjour
je ne pense pas que la primitive wait() (sauf erreur de ma part) puisse éviter des zombies car elle suspend l'exécution du processus appelant jusqu'à ce que l'un de ses fils se termine mais ici en a plusieurs fils donc il est préférable d'utiliser par précaution waitid() qui fournit un contrôle plus précis sur les changements d'états des fils que l'on attend / waitpid()
à bientôt
3
chris79 Messages postés 97 Date d'inscription   Statut Membre Dernière intervention   25
 
Quand un fils meurt, il devient zombie jusqu'à ce que son code de retour soit lu par le père.
(Par contre si le père est déjà mort quand le fils se finit, le fils est temporairement adopté par un autre process (init) le temps de lire son code de retour...mais c'est pas la question ici).

La fonction wait() permet à un père d'attendre le premier fils qui meurt et de lire son code de retour.
Dans notre cas, un père n'a pas plus d'un fils donc wait() semble bien adapté à la situation.
0
sambia39 Messages postés 610 Date d'inscription   Statut Membre Dernière intervention   49 > chris79 Messages postés 97 Date d'inscription   Statut Membre Dernière intervention  
 
Bonsoir
Certes la primitive
 wait() 
est peut-être adaptée mais ici il est question de créer 3 fils donc la manière la plus optimal est un contrôle sur le statut des fils qui suspend par la même occasion le père ( qui est en attente de la mort de tous ces fils en claire
 waitpid() 
est largement mieux adapté ).

De plus le code sources ou le pseudo-algorithme que vous avez fourni ne répond pas à la question poser sur la création de 3 fils sauf erreure de ma part. Voici une version qui est répond au mieux à ce qui a été demandé; reste à l'optimiser voir corriger et l'adapter aux besoins et sauf erreur de ma part elle crée bien le nombre exact de fils contrairement à votre solution.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

#define MAX_SON	100
#define VALEUR	101

int main( void ){

	pid_t t_pid[MAX_SON];
	int i, j, i_statut, i_ret_pid;

	/* Creation des fils */
	for( i = 0; i < MAX_SON; i++ ){
		if( (0) == ( t_pid[i] = fork() ) )
			exit( VALEUR + i );
	}

	i = j= 0;
	/*	Attente et contrôle de fin de fils
	 *  fils en ordre croisant				*/
	while( (0) < ( i_ret_pid = waitpid( t_pid[i++], &i_statut, 0 )) ){
		if( WIFEXITED( i_statut ) ){
			fprintf( stdout, "(%d)Fil[%d]|%d\n",
					j++, i_ret_pid,WEXITSTATUS( i_statut ) );
		}else
			fprintf( stdout, "Erreur fils N=%d\n", j );
	}

	if( (ECHILD) != errno ){
		fprintf( stderr, "(%d)\t:Erreur fils / process ", errno );
		return ( EXIT_FAILURE );
	}
	return ( EXIT_SUCCESS );
}

à bientôt
0
don8 > sambia39 Messages postés 610 Date d'inscription   Statut Membre Dernière intervention  
 
Il ne s'agit pas de créer 3 fils, sambia39, vous avez très mal compris la question posée au départ. La réponse de chris79 est nettement satisfaisant; il y a à chaque fois un seul fils et un seul père, on a ainsi plusieurs générations. En d'autres termes c'est la généalogie d'une seule personne.
0
sambia39 Messages postés 610 Date d'inscription   Statut Membre Dernière intervention   49
 
Bonjour
Désoler si je n'ai pas compris au départ mais n'empêche que l'algorithme donné ou à implémenter n'est pas correct. Si l'on continue sur la lancer de l'algo à mon avis en crée beaucoup trop de fils parce que chaque père recrée des fils à chaque tour de la boucle while et non X processus souhaiter de plus en obtient pas une structure en arbre souhaité. Il ne suffit pas que de mettre des parenthèses et des points virgule pour obtenir un arbres Si c'est pour avoir un arbre de filiforme de x processus alors le code se présentera sous cette forme
void f_Create_abr_fili( unsigned int max ){
	fprintf( stdout, "(%d)Process\t:%d >> fils \t:%d\n",
			max,getpid(), getppid() );
	if( (0) < max && (0) == fork() )
		f_Create_abr_fili_rec( max -1 );
	else{
		wait( NULL );
		exit( 0 );	/*	pas d'exite perte d'arbre	*/
	}
}

ou
void f_create_abr_fili( unsigned int const max ){
	unsigned int i = 0;
	for( i = 0; i < max; i++ ){
		if( (0) == fork() )
			fprintf( stdout, "(%d)\t%d\t: fils %d\n", i, getpid(), getppid() );
		else{
			wait( NULL );
			exit( 0 );	/*	pas d'exite perte d'arbre	*/
		}
	}
}

à bientôt
0
chris79 Messages postés 97 Date d'inscription   Statut Membre Dernière intervention   25 > sambia39 Messages postés 610 Date d'inscription   Statut Membre Dernière intervention  
 
Slt sambia39,

D'abord merci pour tes remarques, c'est toujours intéressant de partager les points de vue ;)

Dans mon algo, le père ne recrée pas de fils à chaque boucle while ...ou alors un truc m'a échappé ;) (je bois pas mal de bières qd il fait chaud donc c'est pas impossible ^^)

Sinon je ne vois pas de différence entre mon algo (où il manquait le wait ...mais ça ne faisait pas partie de l'énoncé...I love zombie ^^) et ta dernière fonction à la différence près que tu utilises une boucle for et moi un while...
Ci-dessous mon algo dans une belle fonction :

void f_create_abr_fili( unsigned int const max )
{
    int nbDeFilsNeeded=max;
    while (nbDeFilsNeeded)
    {
       // Creation d'un fils
       if( (0) == fork() )
       {
          // Le fils.
          fprintf( stdout, "(%d)\t%d\t: fils %d\n", nbDeFilsNeeded, getpid(), getppid() );
          // Un fils vient d'être créé, on décrémente la variable qui comptabilise tout ça.
          nbDeFilsNeeded--;
       }
       else
       {
          // Le pere a créé un fils, on interrompt la boucle et attend la fin de l'UNIQUE fils.
          nbDeFilsNeeded = 0;
          wait(NULL);
       }
    }
}
0
chris79 Messages postés 97 Date d'inscription   Statut Membre Dernière intervention   25
 
Salut,

Je pense qu'avec une boucle while et un fork cela devrait le faire genre :

//init
nbDeFils=3
while nbDeFils
{
   // Creation d'un fils
   pidRes=fork()
   if pidRes == 0
      // Le fils.
         nbDeFils--;
   else
      // Le pere
      nbDeFils = 0
    fi
}
}   
//exit


C'est juste pour l'algo...maintenant faut mettre les parenthèses et les points virgules ^^
0
don8 Messages postés 12 Date d'inscription   Statut Membre Dernière intervention  
 
Merci bcp chris79. Ca marche, sauf qu'il faut au préalable ajouter wait() avant nbDeFils = 0 à fin de permettre d'abord aux fils de s'exécuter.

Merci bcp
0
chris79 Messages postés 97 Date d'inscription   Statut Membre Dernière intervention   25
 
Oui ça évite les zombies ^^
0