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 :

Programmation Système en C : Signaux et Threads


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2014
    Messages : 21
    Par défaut Programmation Système en C : Signaux et Threads
    Bonjour à tous.

    Je vous explique mon cas. Pour plusieurs raisons, j'ai le besoin mais aussi l'envie d'apprendre la programmation système en C sous LINUX. Je m'y suis mis plusieurs fois cette année mais là, depuis deux semaines, je peux y porter vraiment attention.

    J'ai suivi le cours d'un professeur. Aujourd'hui j'ai un exercice BILAN on va dire. Mais je bloque sur certaines questions ou termes…

    Donc je vous propose de vous montrer le code, dire ce qui ne va pas et j'espère que vous pourrez m'aider. Le code :

    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
    #include <time.h>
     
    #define DUREE_MAX   3
     
    #define CHECK(sts,msg) if ((sts) == -1) { perror(msg); exit(sts); }
     
    void Fils (int myPID, unsigned int consigne)
    {
        unsigned int etat = 0;
    int lol2 = getppid();
    printf("lol2 = %d\n", lol2);
        do
        {
            printf("\nProcess n° %d (PID=%d) : Consigne = %d, Etat = %d",
                   myPID, getpid(), consigne, etat);
            sleep(1 + rand() % DUREE_MAX);   // temps de réalisation d'un pas de consigne
            etat++;
        }while (etat < consigne);
        printf("\nProcess n° %d (PID=%d) INACTIF : Consigne %d ... atteinte",
    			myPID, getpid(), consigne);
        printf("\n\t**********************************************************************\n");
    }
     
    void tuerLesFils(void)
    {
        // Ce traitement est activé sur réception du signal SIGUSR1
        // Proposer une implémentation à base de thread
        // A compléter
    }
     
    void acquitterLesFils(void)
    {
        // Gérer la fin des processus fils à base de la signalisation fils/père
        // A compléter
    }
     
    void creerFils(unsigned int consigne)
    {
        int pid;
        static int myChild = 1;
     
        CHECK(pid=fork(),"Ne peut pas forker");
        if (pid == 0)
        {
            Fils (myChild, consigne);
            exit(consigne);
        }
        printf("\tProcessus de régulation n° %d (PID=%d) est actif\n", myChild, pid);
        printf("\t______________________________________________________________________\n");
        myChild++;
    }
     
    int main (int argc, char **argv)
    {
    	unsigned int myConsigne;
     
    	sigset_t intmask;                                                   
            int sts;
     
    	srand(time(NULL));
     
        printf("\tCe programme (incomplet) permet de lancer des processus de régulation\n");
        printf("\tChaque processus prend en paramètre une consigne saisie au clavier\n");
        printf("\t######################################################################\n");
     
    // BLOQUER LE CONTROLE-C
    	// Initialise et affecte le masque                                  
            sts = sigemptyset(&intmask);                                        
            CHECK(sts, "appel de sigemptyset");
            sts = sigaddset(&intmask, SIGINT); 
            CHECK(sts, "appel de sigaddset");
            // On interdit le control-C
            sts = sigprocmask(SIG_BLOCK, &intmask, NULL);
            CHECK(sts, "appel de sigprocmask");
    	printf("\nATTENTION : Le CONTROLE-C est désactivé tout au long du programme\n\n");
    	printf("\t######################################################################\n");
     
        tuerLesFils();
     
        while (1)
        {
            printf("\nDonnez une série de consignes de régulation (>0) (^D=fin) : ");
            if (scanf("%u", &myConsigne) != EOF) 
                creerFils(myConsigne);
            else 
                raise(SIGUSR1);
        }
     
        return EXIT_SUCCESS;
    }
    Donc c'est un programme qui s’exécute en boucle et lance des processus fils dits de régulation avec une consigne saisie au clavier. Ce programme ne gère par la terminaison des processus fils, ni la fin de programme. Nous considérerons également que les processus de régulation partagent une ressource critique. LE PROGRAMME EST DONC INCOMPLET.

    Il y a donc plusieurs questions auxquelles il faut répondre.
    La première demande de bloquer le CONTROLE-C dans le père et dans le fils. Les lignes que j'ai ajoutées (après // Blocage Controle-C) bloquent ce signal et ça fonctionne. Déjà ce bout de code vous paraît-il bien ?

    Mon principal problème concerne les questions d'après. La deuxième question :

    Rappeler quel est le signal généré par un processus lorsqu'il se termine, à destination de son processus père.

    Compléter le processus père de façon à ce qu'il acquitte la terminaison d’un processus fils.


    Déjà c'est super mal posé, j'ai l'impression. Je pensais à : envoyer le signal SIGCHLD au père quand le fils est fini et pour pas avoir de zombie, quand le père reçoit ce signal il fait un wait(3). Ça parait bon ? ^^

    Et là vient le calvaire : La saisie de contrôle-D termine la saisie et provoque l’émission du signal SIGUSR1 vers le processus lui-même.
    Compléter la fonction tuerLesFils() qui met en œuvre un thread qui se chargera d’attendre ce signal (pause()). Sur réception de SIGUSR1, le thread alors termine tous les processus fils en cours.


    Je ne comprends pas du tout la question... et je ne sais pas du tout la mettre en œuvre

    Merci d'avance à ceux qui pourront m'aider, et désolé de la taille du post.

    Bonne journée,
    Fuot.

  2. #2
    Membre Expert
    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
    Par défaut
    1) Ca m'a l'air bon effectivement

    2) La question est bien posée. SIGCHLD est envoyé automatiquement par un processus fils à son père au moment de la terminaison. Tu n'as pas à l'envoyer explicitement. Effectivement il faut écouter installer un handler pour SIGCHLD dans le père, et dedans faire un wait() pour récupérer le status du fils qui vient de terminer.

    3) Qu'est-ce qui te pose problème plus exactement ? La façon dont ils te demandent de régler le problème est un peu étrange, mais pourquoi pas. Regarde du côté de pthread_create() pour créer un thread qui exécutera tuerLesFils(). Il faudra je pense que tu créé un handler pour SIGUSR1 dans lequel tu positionneras un flag, que le thread "tuerLesFils" pourra tester quand pause() retourne.

  3. #3
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2014
    Messages : 21
    Par défaut
    Bonjour et merci beaucoup de cette première réponse.

    Pour la 2). :

    Ok, un fils envoie automatiquement SIGCHLD à son père quand il se termine. Mais je ne comprend pas vraiment à quel moment il le fait dans CE programme.
    Pour la suite j'ai compris. Je pense faire dans le père quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    signal(SIGCHLD, acquitterLesFils);
    et dans le fonction acquitterLesFils je fais un wait() ??

    Pour la 3) : j'ai compris ce que tu as dis je pense. Il faut que je crée le thread dans le fils, ce thread exécute le fonction tuerLesFils. Dans cette fonction je crée le handler pour SIGUSR1 et j'exécute pause() jusqu'à recevoir SIGUSR1 ? quand je le reçois, je dois terminer tous les processus fils mais comment ? (kill(pid, SIGKILL) ???)

    Merci de ton aide en tout cas

  4. #4
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2014
    Messages : 21
    Par défaut
    J'ai réussi pour les deux questions . sauf un petit truc pour la question 3, j'arrive bien a créer le thread et attendre avec pause(). cependant quand je reçois SIGUSR1, il faut tuer tous les fils et je n'arrive pas car je ne sais pas comment récupérer les PID de tous les fils pour les kill(pid, SIGKILL)

    Pouvez-vous m'éclairer s'il vous plait ?

    En tout cas merci beaucoup pour tout déjà, j'ai bien avancé

  5. #5
    Membre Expert
    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
    Par défaut
    Un solution pourrait être d'enregistrer les pid des fils (récupérés par le père lors du fork) dans un tableau (ou une liste chainée) global auquel le thread aura accès. Il faut par contre faire attention à sérialiser les accès au tableau pour éviter que le thread n'y accède alors que le thread principal est en train de le mettre à jour.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 23/10/2014, 08h20
  2. Réponses: 4
    Dernier message: 28/11/2013, 20h40
  3. Programmation Système : Signaux
    Par fred44ooo dans le forum Linux
    Réponses: 7
    Dernier message: 04/05/2010, 09h13
  4. Programmation système
    Par spynux dans le forum Général Java
    Réponses: 1
    Dernier message: 04/11/2005, 10h40
  5. [Programmation système] Programme de base
    Par tooney dans le forum C
    Réponses: 7
    Dernier message: 11/07/2005, 21h36

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