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 :

[Débutant] Problème de compilation / utilisation de signaux


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 9
    Points : 9
    Points
    9
    Par défaut [Débutant] Problème de compilation / utilisation de signaux
    Bonjour,

    J'essaie en ce moment de comprendre les interractions entre processus enfants et parents, et plus précisement d'envoyer un signal d'un parent à un enfant.
    J'ai récupéré un code sur internet (que j'ai légèrement modifié), mais je me heurte à des erreurs que je n'arrive pas à comprendre.

    Le principe du programme est simple, je fais un fork(), et je veux que le parent envoie des signaux séparés de 3 secondes à l'enfant pour lui dire d'écrire un truc dans la console avec printf.

    Mon problème est que qu'après avoir compilé une fois, je n'ai pas les mêmes résultats quand j'exécute plusieurs fois d'affilée le programme. Exemple :


    Nom : Screenshot from 2014-05-17 17:55:59.png
Affichages : 162
Taille : 528,0 Ko
    (Dsl pour la taille de l'image, mais c'est illisible quand j'essaie de la réduire).
    Quand j'exécute la 1ere fois (./test1), j'ai une réponse de l'enfant au premier signal, alors que sans rien changer quand j'exécute la seconde fois (./test2), je n'ai plus aucune réponse au 1er signal)


    Mon code est le suivant, j'espère que vous pourrez m'aider :


    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
     
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <sys/wait.h>
     
    void banane(); 
    void sigint();
    void sigquit();
    void sigusr1();
     
    main()
    { 
    int pid;
    int k;
     
      /* get child process */
     
       if ((pid = fork()) < 0) {
            perror("fork");
            exit(1);
        }
     
       if (pid == 0)
         { /* child */
    	k=0;
          signal(SIGHUP,banane); /* set function calls */
          signal(SIGINT,sigint);
          signal(SIGQUIT,sigquit);
          signal(SIGUSR1,sigusr1);
         }
      else /* parent */
         {  /* pid hold id of child */
    	k=2222;
    	printf("\nPARENT: sending SIGUSR1\n\n");
    	kill(pid,SIGUSR1);
    	sleep(3);/* pause for 3 secs */
           printf("\nPARENT: sending SIGHUP\n\n");
           kill(pid,SIGHUP);
           sleep(3); /* pause for 3 secs */
           printf("\nPARENT: sending SIGINT\n\n");
           kill(pid,SIGINT);
           sleep(3); /* pause for 3 secs */
           printf("\nPARENT: sending SIGQUIT\n\n");
           kill(pid,SIGQUIT);
           sleep(1);
         }
    return 0;
    }
     
    void sigusr1()
    {signal(SIGUSR1,sigusr1);
    printf("CHILD: I have received a SIGUSR1\n");
    }
     
    void banane()
     
    {signal(SIGHUP,banane);
       printf("CHILD: I have received a SIGHUP (banane)\n");
    }
     
    void sigint()
     
    {signal(SIGINT,sigint);
       printf("CHILD: I have received a SIGINT\n");
    }
     
    void sigquit()
     
    { printf("My DADDY has Killed me!!!\n");
      exit(0);
    }

  2. #2
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Tu peux binder tous les signaux (a l'exception de SIGKILL et de SIGSTOP) avec une seule fonction :

    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
    void handle_signal(int sig)
    {
      switch (sig) {
        case SIGINT:
           printf("SIGINT !\n");
           break;
        case SIGUSR1:
           printf("SIGUSR1 !\n");
           break;
       default:
          printf("Unknown signal !\n");
      }
      // to re-init signal function
      signal(sig, handle_signal);
    }
    Il faudrait aussi que tu mettes une boucle infinie dans ton processus fils, quelque chose dans ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while (1) {
      // pour eviter de bouffer tout le CPU
      sleep(10);
    }

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 9
    Points : 9
    Points
    9
    Par défaut
    Tout d'abord, merci de ton aide! J'ai appliqué les corrections que tu suggères, mais celà n'a pas résolu mon problème : à l'execution, l'enfant n'affiche toujours rien.
    Je me retrouve avec ça dans la console :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ./test3
     
    PARENT: sending SIGUSR1
     
     
    PARENT: sending SIGHUP
     
     
    PARENT: sending SIGINT
     
     
    PARENT: sending SIGQUIT
    alors que je voudrais (devrais?) avoir

    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
     
    ./test3
     
    PARENT: sending SIGUSR1
     
     
    Child received SIGUSR1 !
     
    PARENT: sending SIGHUP
     
     
    Child received SIGHUP !
     
    PARENT: sending SIGINT
     
     
    Child received SIGINT !
     
    PARENT: sending SIGQUIT
     
     
    Child received SIGQUIT (daddy killed me)!


    Mon code est actuellement ça, j'ai l'impression qu'il ne fait que la boucle du parent mais que rien n'est reçu par l'enfant :

    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
     
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <sys/wait.h>
     
    void handle_signal(); 
     
    main()
    { 
    int pid;
    int k;
     
      /* get child process */
     
       if ((pid = fork()) < 0) {
            perror("fork");
            exit(1);
        }
     
       if (pid == 0)
         { /* child */
    	k=0;
          signal(SIGHUP,handle_signal); /* set function calls */
          signal(SIGINT,handle_signal);
          signal(SIGQUIT,handle_signal);
          signal(SIGUSR1,handle_signal);
    	while(1)
    	{sleep(1);}
         }
      else /* parent */
         {  /* pid hold id of child */
    	k=2222;
    	printf("\nPARENT: sending SIGUSR1\n\n");
    	kill(pid,SIGUSR1);
    	sleep(3);/* pause for 3 secs */
           printf("\nPARENT: sending SIGHUP\n\n");
           kill(pid,SIGHUP);
           sleep(3); /* pause for 3 secs */
           printf("\nPARENT: sending SIGINT\n\n");
           kill(pid,SIGINT);
           sleep(3); /* pause for 3 secs */
           printf("\nPARENT: sending SIGQUIT\n\n");
           kill(pid,SIGQUIT);
    	sleep(1);
    	wait(NULL);
         }
    return 0;
    }
     
    void handle_signal(int sig)
    {
      switch (sig) {
        case SIGINT:
           printf("Child received SIGINT !\n");
           break;
        case SIGUSR1:
           printf("Child received SIGUSR1 !\n");
           break;
        case SIGHUP:
           printf("Child received SIGHUP !\n");
           break;
        case SIGQUIT:
           printf("Child received SIGQUIT (daddy killed me)!\n");
           exit(0);
           break;
       default:
          printf("Unknown signal !\n");
      }
      // to re-init signal function
      signal(sig, handle_signal);
    }
    Des idées?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Sous cygwin ton code fonctionne

    Déjà ta "forward declaration" est mauvaise

    En C, il est grandement recommandé de mettre un void lorsqu'il n'y a pas de paramètre void handle_signal(void)Et évite aussi les retours implicites

  5. #5
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    La fonction est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void handle_signal(int) {
    //...
    |
    }
    Mais tu la declares :

    Pas sur que ce soit tip top...

    Je pense qu'il faudrait que le processus pere attende un peu avant d'envoyer son premier signal aussi (un peu petit appel a sleep devrait resoudre le probleme).

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 9
    Points : 9
    Points
    9
    Par défaut
    Merci beaucoup!

    Le problème venait effectivement de la necessité d'avoir un sleep() au début de la fonction du parent, celà marche maintenant!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     .....
               else /* parent */
           { 
            /* pid hold id of child */
    	usleep(1000);
    	printf("\nPARENT: sending SIGUSR1\n\n");
    	kill(pid,SIGUSR1);
            ....

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

Discussions similaires

  1. |Java| Débutant : Problème à la compilation
    Par juninho dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 14/03/2008, 19h39
  2. Débutant : Problème de compilation ou d'exécution
    Par infolove dans le forum Général Java
    Réponses: 14
    Dernier message: 29/01/2008, 22h08
  3. [débutant] problème de compilation
    Par shinkyo dans le forum GLUT
    Réponses: 4
    Dernier message: 21/05/2006, 15h18
  4. [JUnit] [Débutant] Problème avec l'utilisation de JUnit
    Par Juanito-Toto dans le forum Tests et Performance
    Réponses: 2
    Dernier message: 22/12/2005, 16h49
  5. [débutant] problème de compilation
    Par LaseLiep dans le forum C
    Réponses: 12
    Dernier message: 16/12/2005, 20h40

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