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

POSIX C Discussion :

Processus zombies ne se terminent pas malgré SIG_CHLD


Sujet :

POSIX C

  1. #1
    Membre expérimenté
    Avatar de muad'dib
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    1 011
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2003
    Messages : 1 011
    Points : 1 375
    Points
    1 375
    Par défaut Processus zombies ne se terminent pas malgré SIG_CHLD
    Bonjour à tous,

    Voila j'ai une application de client-serveur basé sur des fork() : à chaque connexion d'un client, un processus fils est créé jusqu'à la déconnexion de celui-ci.
    Lorsque je connecte un client par seconde, le processus zombie est bien détruit, mais lorsque je simule une grosse charge du serveur (genre 100 connexions par seconde) des processus zombies restent présents dans la liste des processus.

    Je sais qu'une telle charge est rare mais cela peut arriver. Voici une partie de code pour illustrer ce que je fais.
    Chez le client:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    do {
        usleep(1000);
        sockfd = connect_server("127.0.0.1", 9611);
     
        if (sockfd > 0) {
            send_data(sockfd, "test\n");
     
            close_connection(sockfd);
        }
    }
    while (1);
    Sur le serveur:
    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
    	/* Un cliente se ha conectado */
    		pid = fork();
     
    		if(pid < 0)
    		{
    			result = E_CANT_FORK;
    		}
    		else if(pid == 0)
    		{
    			result = create_new_client_process(sockfd);
     
    			memset(&msgdisbuf, 0, sizeof(msgdisbuf));
    			msgdisbuf.type = MSGDISTYPE;
    		    memcpy(&msgdisbuf.sockfd, &sockfd, sizeof(sockfd));
     
     			if (msgsnd(msgdisid, &msgdisbuf, sizeof(msgdisbuf.sockfd), IPC_NOWAIT) < 0) 
    			{
    		        perror("msgsnd");
    		    }
     
    			exit(0); /* Finalizar proceso hijo */
    		}
    Au lancement du programme j'appelle la méthode sig_chld(); définie comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void sig_chld() {
    	signal(SIGCHLD, SIG_IGN);
    	wait(NULL);
    	signal(SIGCHLD, sig_chld);
    }

  2. #2
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Pour répondre à cette question, il faut considérer plusieurs points :
    Le comportement de la fonction signal est différent d'un système à l'autre, par exemple sous linux, signal réinstalle automatiquement le gestionnaire sauf si la constante _XOPEN_SOURCE est définie; de plus si un signal arrive entre l'entré dans le gestionnaire et signal(SIGCHLD,SIG_IGN) , le signal ne sera pas traité et le process ne sera pas adopté par init (et c'est ce qui se passe quand le serveur est surchargé).
    J'ajoute que tu ne testes pas le retour de signal, qui peut échouer et que de plus, la norme SUS3 déconseille signal(SIGCHLD,SIG_IGN) .
    Si tu veux être vraiment propre et portable voilà ce que je conseille :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct sigaction action;
    action.sa_handler=SIG_IGN;
    sigemptyset(&(action.sa_mask));
    action.sa_flags=SA_RESTART|SA_NCLDSTOP;
    if(sigaction(SIGCHLD,&action,NULL)!=0)
    {
      perror("erreur");
      exit(EXIT_FAILURE);
    }
    Cordialement.
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  3. #3
    Membre expérimenté
    Avatar de muad'dib
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    1 011
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2003
    Messages : 1 011
    Points : 1 375
    Points
    1 375
    Par défaut
    Super ça fonctionne impeccable comme ça, merci beaucoup l'ami !

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

Discussions similaires

  1. Frame et terminal pas d'accord....
    Par superjoe dans le forum 2D
    Réponses: 3
    Dernier message: 23/03/2006, 15h30
  2. [AJAX] Ma fonction ne se termine pas...
    Par Davboc dans le forum Général JavaScript
    Réponses: 17
    Dernier message: 08/03/2006, 12h05
  3. [Process][exec] processus qui ne se termine jamais?
    Par la.musaraigne dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 15/06/2004, 14h02
  4. [reseaux] Processus zombie...
    Par dclink dans le forum Programmation et administration système
    Réponses: 4
    Dernier message: 10/09/2003, 10h30
  5. [TTHREAD] ne termine pas sont exécution
    Par Bbenj dans le forum Langage
    Réponses: 4
    Dernier message: 02/08/2002, 16h42

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