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

Linux Discussion :

processus et signaux UNIX


Sujet :

Linux

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 4
    Points : 1
    Points
    1
    Par défaut processus et signaux UNIX
    Bonjour,

    J'aurais voulu savoir qi vous pouviez m'aider dans la compréhension des processus et des signaux sous Unix à travers qq exemples.

    1) J'ai le prog suivant:

    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
    #include <stdio.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <unistd.h>
    int main (void) {
    void fonc (int Sig);
    int i;
    for (i=1; i < NSIG; i++) signal (i, fonc);
    for (i=1; i < NSIG; i++) kill (getpid(), i);
    return 1;
    }
    void fonc (int Sig){
    printf ("Recu signal %d\n", Sig);
    signal (Sig, fonc);
    }
    Je dois repondre a la question: combien de fois s'affiche les message "reçu signal ..." et pourquoi?

    J'aurais tendance à dire qu'il faille inverser les deux lignes des for pour d'abord envoyer les signaux et après les traiter avec la fonction fonc.
    Est-ce correct?

    2) J'ai un deuxieme prog:

    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
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <stdlib.h>
    #define N 100000
    int main (void) {
    int ret_fork, Etat, i;
    void fonc(int NumSig);
    ret_fork= fork();
    if (ret_fork == 0) {
    kill(getppid(), SIGUSR1);
    exit(1);
    }
    if (ret_fork > 0){
    for (i=0; i<N ; i++); /* boucle exécutée N fois */
    signal(SIGUSR1, fonc);
    wait(&Etat);
    }
    return 0;
    }
    void fonc(int NumSig){
    printf("Signal SIGUSR1 recu\n");
    signal(NumSig, fonc);
    }
    Le probleme est que je n'arrive pas a voir ce que fait ce programme et combien de lignes vont etre affichées apres son execution.

    3) C'est sur fork avc le prog:

    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
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    int main(void) {
    int ret_fork, Etat;
    ret_fork = fork();
    if( ret_fork == 0 ) {
    fork();
    printf("1-Pid %d fils de %d\n", getpid(), getppid());
    exit(0);
    } else {
    printf("2-Pid %d fils de %d\n", getpid(), getppid());
    wait(&Etat);
    exit(0);
    }
    return 0;
    }
    Est ce bien 3 lignes qui seront affichées par ce programme.
    Apres ret_fork = fork(); deux processus executent la suite du code: le fils qui obtient 0 comme resultat du fork execute le premier if à l'interieur duquel on a de nouveau un fork donc deux processus vont executés le printf qui suit donc deux lignes. Puisle pere issu du premier ret_fork = fork();, execute ce qu'il y a dans le else car il a pour resultat du fork le numero de son fils donc pas 0 d'ou la troisieme ligne affichée ici. Donc au total on a trois lignes?

    Est-ce correct?

    Voila, si quelqu'un pouvait me corriger et m'expliquer mes erreurs et l'exemple 2 en particulier ce seait sympa car j'apprend seul unix donc c'est pas toujours facile...

    En vous remerciant par avance.

  2. #2
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 129
    Points
    28 129
    Par défaut
    Bonjour,

    Je pense que tu devrais commencer par le commencement : apprendre le langage C avant de commencer à jouer avec les signaux. Tu trouveras de très bons cours sur http://c.developpez.com

    Ensuite, pour les signaux, il faut savoir que le handler de signal (c'est à dire la fonction dans laquelle tu gères les signaux) doit en faire le moins possible. Idéalement, cela consiste à changer une variable, pas plus. Donc surtout pas de printf dedans.

    Premier exemple :
    tu définis un handler, que tu appelles fonc. Ce handler, lorsqu'il intercepte un signal, va afficher quelque chose (c'est mal), et se réarmer sur le signal.
    Ensuite, tu définis que pour tous les signaux définis par la première boucle for (donc tous ceux numérotés de 1 à NSIG (qui ne semble pas défini)).
    Ensuite, tu envoies à ton processus un signal i (de 1 à NSIG là aussi).
    Donc là, tu vas attraper chacun des signaux, et appeler fonc dessus, puis réarmer.
    Et enfin le programme se finit.

    Donc en théorie, tu devrais afficher NSIG fois ton message, à condition que le fait de coder une fonction de traitement des signaux non atomique ne te pose pas de problème (signaux perdus, passés à d'autres processus, ...), et qu'il soit possible d'attraper le signal.

    Second programme :
    Tu appelles fork(). Donc tu as maintenant deux processus. On va supposer que l'appelle à fork() fonctionne.

    Le fils va exécuter le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if (ret_fork == 0) {
    kill(getppid(), SIGUSR1);
    exit(1);
    }
    /* J'ai enlevé le code du père pour plus de lisibilité */
    return 0;
    C'est à dire qu'il va lancer un signal SUGUSR1 à son processus père (la fonction getppid retourne le PID du père).

    Le père va exécuter le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (ret_fork > 0){
    for (i=0; i<N ; i++); /* boucle exécutée N fois */
    signal(SIGUSR1, fonc);
    wait(&Etat);
    }
    return 0;
    C'est à dire qu'il arme, pour chaque signal de numéro inférieur à N, un handler de signal qui sera la fontion fonc().
    Celle-ci est identique au premier exemple : elle affiche un message (c'est mal), et réarme le handler de signal pour pouvoir retraiter le même signal si besoin plus tard.
    Ensuite le wait() indique qu'il attend que son fils se soit terminé.

    Plusieurs comportements possibles :
    Le fils s'exécute en premier : le signal est lancé avant que le père n'arme les handler de signaux. Le comportement devient probablement dépendant de l'OS, mais il faudrait vérifier.
    Le père s'exécute en premier : le handler est en attente, le père aussi. Le fils va alors s'exécuter, lançant son signal. Celui-ci sera catché par le père, qui va donc afficher une phrase, puis tout le monde va se terminer tranquillement.

    Pour le troisième cas, je pense que l'explication du fork() ci-dessus est suffisante


    [edit] Corrections du post suite aux differentes remarques.

  3. #3
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    La première question est est une question piège, la deuxième aussi, la troisième je ne crois pas ...

  4. #4
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Merci gangsoleil d'avoir pris le temps de me répondre.

    Mais pour le cas numéro 2 il y a toujours quelques petits points que je ne comprends:

    1/ si le fils s'execute en premier, le pere ne prendra-t-il jamais la main donc ds ce cas le programme ne rendra aucune ligne? tu dis que le comportement dependra de l'OS, peux-tu préciser pourquoi et comment stp?

    2/ si le pere s'execute en premier tu as écris: "... les handlers sont en attente, le père aussi. Le fils va alors s'exécuter, lançant son signal. Celui-ci sera catché par le père, qui va donc afficher une phrase, puis tout le monde va se terminer tranquillement."
    Est-ce qu'un seul signal va etre catché par le pere ou bien les N signaux vont l'etre et dans ce cas on aura N fois la phrase "Signal SIGUSR1 recu"?
    Est-ce que tu pourrais aussi me décrire brievement ce que fait wait(&état) pour le père? cela signifie-t-il seulement qu'il attend la fin du fils? et ds le cas ou le pere s'execute en premier, il n'a pas à attendre la fin du fils donc que fait wait dans ce cas?



    D'autre part, j'avais aussi des questions sur la synchronisation.
    J'essaye de resoudre qq exos pr m'entrainer mais je bloque sur celui la:

    Le processus R doit écrire un message dès que l’un des processus P1 à P5 se termine.
    Ordonnancement par quantum de temps. Tous les processus ont la même priorité. R ne
    démarre pas le premier.

    Variables partagées par tous les processus :
    - un sémaphore S initialisé par : init(S,1)
    - la variable NProc initialisée à 0

    Programme exécuté par le processus R:
    #define MAX 5
    int main (void) {
    while (NProc< MAX){
    P(S);
    ...
    printf(«Processus terminés :%d\n», NProc);
    V(S);
    };
    }


    Programme exécuté par les processus P1 à P5:
    int main (void) {
    P(S);
    ...
    NProc= NProc + 1;
    V(S);
    }

    On veut que R affiche un message chaque fois qu’un processus Pi se termine.

    En fait, j'arrive pas à voir ce que fair R (même si je pense qu'il va y avoir un probleme) et où mettre un sémaphore pour remedier à ce probleme.

    Voila, si vous pouviez m'expliquer tout cela, ce serait sympa.

    Merci beaucoup.

  5. #5
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    Citation Envoyé par doogy3 Voir le message
    1) ...
    J'aurais tendance à dire qu'il faille inverser les deux lignes des for pour d'abord envoyer les signaux et après les traiter avec la fonction fonc.
    Est-ce correct?
    Non. Il faut d'abord installer un gestionnaire de signal avant de le solliciter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    combien de fois s'affiche les message "reçu signal ..." et pourquoi?
    Huit fois sur tous les Unix/Linux connus, et pas NSIG comme on pourrait le croire. C'est le piège dont je parlais.

  6. #6
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Salut,

    alors la je vois pas du tout pourquoi ca s'afficherait que huit fois (a ma connaissance NSIG va de 1 à 32) et non pas NSIG-1 fois?!?

    Peux-tu m'expliquer pourquoi selon toi c'est huit fois seulement?

  7. #7
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    Ce n'est pas "selon moi" mais selon le standard POSIX.

    Je te conseille de compiler et tester le code sur ta machine, d'observer le résultat et de lire les pages de manuel consacrées aux signaux pour t'en convaincre.

  8. #8
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Ca s'affiche 8 fois parce que le signal 9 est SIGKILL, qui ne peux pas être intercepté et tue le processus sans autre forme de procès (tu sais, le fameux kill -9 <pid>).

  9. #9
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    merci matafan pour ta réponse. effectivement, le signal SIGKILL arrete le processus en cours donc j'aurais que 8 affichages.

    Sinon est-ce que t'as une idée pour mes questions qui subsistent (le post 4 je crois?). je m'en sors pas trop a vrai dire...

    merci

  10. #10
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    Quelques remarques sur la question 2:

    Il n'y a pas N signaux émis mais un seul. Le résultat n'est pas prédictible. Rien ne permet de garantir l'ordre d'exécution du code et le signal sera peut-être émis avant que le handler ne soit installé, en particulier si le CPU est lent. Dans ce cas, ça dépend effectivement de l'OS. Solaris par exemple affiche "User signal 1".

    A propos, il n'y a qu'un seul handler d'installé et non pas N comme gangsoleil l'a écrit par erreur.

Discussions similaires

  1. Processus et signaux
    Par nioney dans le forum C
    Réponses: 6
    Dernier message: 12/06/2013, 17h16
  2. Masquer sous unix un processus ou ses arguments
    Par alainmahe dans le forum Linux
    Réponses: 6
    Dernier message: 08/12/2006, 13h02
  3. Réponses: 1
    Dernier message: 03/12/2006, 10h16
  4. Communication processus et signaux
    Par ph086 dans le forum POSIX
    Réponses: 4
    Dernier message: 10/11/2006, 15h37
  5. Probleme de boucle avec des processus sous UNIX
    Par sebastieng dans le forum POSIX
    Réponses: 6
    Dernier message: 15/10/2005, 18h57

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