Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 18/10/2016, à 17:45

DonutMan75

[RESOLU] [C] Limiter le nombre de fils créé par le processus père

Bonsoir à tous,
j'aimerais développer un petit script en C qui va ouvrir un certain nombre de processus fils... et j'aimerais limiter le nombre de fils ouvert à un instant t.
J'ai lu plusieurs solutions (compliquées) sur le net mais rien qui ne m'ait vraiment convaincu...

J'essaie ici une méthode basée sur le signal SIGCHLD qui est envoyé par un fils à son père au moment de mourir (c'est d'une tristesse tout ça....).

J'aimerais avoir le retour de développeurs un peu plus confirmés que moi pour savoir si c'est du "code propre".
En pratique, ça a l'air de bien fonctionner....

Merci d'avance pour vos retours et commentaires !


L'idée

On créé un compteur nson qui va représenter le nombre de fils ouvert à un instant t.

On va incrémenter nson chaque fois qu'on créé un fils.
On va décrémenter nson chaque fois qu'un fils meurt.

    Incrémenter nson

Incrémenter nson est assez simple, il suffit par exemple de faire :

pid = fork()

if (pid != 0) // PERE
	{
	nson++; // On a créé un fils, on incrémente nson.
	}

    Décrémenter nson

Décrémenter nson est un peu plus délicat. Il faudrait que le père sache quand un de ses fils meurt.

A chaque fois qu'un fils meurt, il envoie le signal SIGCHLD à son papounet.
Il faudrait donc que le père exécute une fonction qui décrémente nson à chaque fois qu'il reçoit un tel signal.
C'est exactement ce que propose la fonction sigaction de la librairie <signal.h>

On commence par définir une structure sigaction qui contiendra, en gros, l'adresse d'une fonction à exécuter. Cette fonction ne fera rien d'autre que décrémenter nson.
On lie ensuite notre structure sigaction à un signal (ici SIGCHLD) à l'aide de la fonction sigaction().

Le code

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#define NSON_MAX 10 // Nombre maximum de fils ouverts à un instant t

void decrementer(); // Cette fonction décrémente le nombre de fils, elle sera appelée chaque fois qu'un fils meurt

int nson = 0; // Nombre de fils, c'est une variable "globale" afin qu'elle puisse être vue par decrementer()

main()
	{
	struct sigaction action; 			// On créé une structure sigaction qui lie un signal (ici SIGCHLD) à une fonction (ici decrementer() décrite plus bas)
		sigemptyset(&action.sa_mask); 		// Liste de sigaux à bloquer lors de l'exécution du handler (ici aucun)
		action.sa_flags = 0; 			// Pas de flags particuliers
		action.sa_handler = decrementer; 	// Notre fameuse fonction decrementer()...
	
	sigaction(SIGCHLD, &action, 0); // La fonction sigaction lie le signal SIGCHLD ) à notre action
	
	pid_t pid;
	
	int i;
	


	for(i=0; i<100; i++)
		{
		
		while (nson > NSON_MAX - 1) // Boucle d'attente : tant qu'il y a trop de fils, le pere patiente 1s
			{
			printf("[PERE] J'ai %d fils ce qui est beaucoup, je vais attendre un peu...\n", nson);
			sleep(1);
			}
			
		pid = fork();
		
		if (pid == 0) // FILS
			{
			/* Traitement du FILS */
			printf("   [FILS %ld] Mon pere est %ld\n", (long) getpid(), (long) getppid());
			
			/* Simulation d'un temps de traitement... */
			sleep(5);

			exit(0);
			}
		else // PERE
			{
			nson++; // On a créé un fils
			printf("[PERE] J'ai cree le fils %ld, j'ai actuellement %d fils...\n", (long) pid, nson);
			}
		
		

		}; // for(int i=0; i<100; i++)
	
	
	} // main


void decrementer()
	{
	nson--;
	}

Dernière modification par DonutMan75 (Le 20/10/2016, à 15:57)

Hors ligne

#2 Le 19/10/2016, à 14:56

DonutMan75

Re : [RESOLU] [C] Limiter le nombre de fils créé par le processus père

Bonjour,
bon j'ai un peu joué avec ps et top et je me suis rendu compte d'une grosse maladresse dans mon code !

En effet, par défaut à la fin d'un fils (le "exit(0)" ci-dessus), le signal SIGCHLD est bien envoyé au PERE.... mais par défaut celui-ci ne prend pas la peine de le traiter et le FILS reste en mode ZOMBIE jusqu'à la fin du PERE.

Pour que le PERE prenne le temps de faire son deuil et que le processus FILS soit détruit, il faut utiliser explicitement la fonction wait() ou waitpid().

Du coup on peut effectuer la décrémentation de nson non pas en handler de la réception de SIGCHLD, mais ajouter ça en conséquence de wait().

Le PSEUDO-CODE ne serait donc plus

Si je reçois un signal SIGCHLD, ALORS je décrémente nson

Mais plutôt :

Si je détecte un FILS ZOMBIE ALORS je le tue PUIS je décrémente nson

L'autre avantage de cela par rapport à ma première méthode est que la table des signaux est binaire (soit 1 soit 0), en particulier si deux signaux arrivent avant le traitement du handler ça comptera que pour une seule terminaison de fils (enfin il me semble ?)

Qu'en dites-vous ?

Merci pour vos retours smile

D.

Dernière modification par DonutMan75 (Le 19/10/2016, à 14:56)

Hors ligne

#3 Le 20/10/2016, à 15:56

DonutMan75

Re : [RESOLU] [C] Limiter le nombre de fils créé par le processus père

Bonjour,
bon je clos ce fil-ci étant donné que mon pseudo-code ici donne de bons résultats. J'ignore s'il existe une méthode plus simple ou plus élégante mais en tout cas, celle-ci semble fonctionner correctement.

D.

Hors ligne