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 :

Communication inter-processus et pause()


Sujet :

POSIX C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juin 2007
    Messages : 106
    Points : 68
    Points
    68
    Par défaut Communication inter-processus et pause()
    Bonjour à tous,

    J'ai deux processus qui communiquent ensemble. Au cours de l'execution du premier, celui se met en pause puis doit se réactiver dès qu'il recoit un signal du second processus.

    Attention, il faut noter que le premier processus est executé dans un thread.

    Voici mon code pour le premier processus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
            void treatSignal(int numero, siginfo_t* info, void* inutile) {
    	printf("signal received from:%d !! \n", info -> si_pid);
            }
     
            void test(void) {
    	struct sigaction action;
    	action.sa_sigaction = treatSignal;
    	sigemptyset(& action.sa_mask);
    	action.sa_flags = SA_SIGINFO;
    	sigaction(SIGUSR1, & action, NULL);
    	int status = pause();
    	printf("WAKE UP\n");
            }
    Le second processus envoi simplement un signal SIGUSR1 au premier. Le signal est bien intercepté mais la fonction pause ne rend jamais la main comme ça devrait être le cas quand un signal est intercepté et que la fonction d'interception finit son traitement.

    Quelqu'un pourrait-t'il m'éclairer?

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Citation Envoyé par jsebfranck Voir le message

    Attention, il faut noter que le premier processus est executé dans un thread.
    non un processus ne s'execute pas dans un thread. Un process c'est un espace d'adressage, un thread c'est une entité d'execution tu en as au moins 1 par processus, le thread primaire.

    est-ce que cela veut dire que tu crées thread secondaire (avec pthread_create par exemple) dans ton premier processus pour gérer le signal ? si oui cela t'es imposé ou c'est un choix que tu as fais ?
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juin 2007
    Messages : 106
    Points : 68
    Points
    68
    Par défaut
    Effectivement, le traitement s'effectue dans un nouveau thread. Ceci m'est imposé pour des raisons complètement différentes.

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Citation Envoyé par jsebfranck Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
            void treatSignal(int numero, siginfo_t* info, void* inutile) {
    	printf("signal received from:%d !! \n", info -> si_pid);
            }
     
            void test(void) {
    	struct sigaction action;
    	action.sa_sigaction = treatSignal;
    	sigemptyset(& action.sa_mask);
    	action.sa_flags = SA_SIGINFO;
    	sigaction(SIGUSR1, & action, NULL);
    	int status = pause();
    	printf("WAKE UP\n");
            }
    pour le handler du signal il faut faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    action.sa_handler=treatSignal
    C'est peut-être du à cela que tu ne sors pas de l'appel à pause

    Ensuite pour les signaux temps réels tu peux utiliser la primitive sigwaitinfo pour un appel bloquant et sigtimedwait pur gérer un timeout (donc non bloquant) cela te permettra de récupérer les paramètres contrairement à pause()

    Le signal est une valeur entière comprise entre SIGRTMIN et SIGRTMAX (voir la différence avec SIGUSR1 car on n'utilise pas ces constantes là normalement)

    normalement ces fonctions sont POSIX voir si la constante _POSIX_REALTIME_SIGNALS est définie.
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juin 2007
    Messages : 106
    Points : 68
    Points
    68
    Par défaut
    Si la valeur de sa_flags est à SA_SIGINFO, c'est le pointeur de fonction de sa_sigaction qui est pris en compte et non sa_handler. Le problème ne vient donc pas de là.

    Je vais essayer les fonctions sigwaitinfo et sigtimedwait à la place de pause pour voir si ça peut résoudre mon problème.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juin 2007
    Messages : 106
    Points : 68
    Points
    68
    Par défaut
    J'ai mis en place le sigwaitinfo. Ca ne résoud pas mon problème mais son utilisation est effectivement beaucoup plus intéressante que la simple fonction pause. Tout est paramétrable et on peut récupérer les infos sur le signal reçu.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            sigset_t sigset;
    	siginfo_t info;
    	sigaddset(&sigset, SIGUSR1);
    	sigwaitinfo(&sigset, &info);
    D'autres idées pour ce problème?

  7. #7
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    utilise

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec timeout);
    tu envois comment le signal au processus depuis une invite de commande/korn shell ou tu as également un programme ?

    tu es sûr que SIGUSR1 est compris entre SIGRTMIN/SIGRTMAX ?
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juin 2007
    Messages : 106
    Points : 68
    Points
    68
    Par défaut
    Pourquoi devrai-je utiliser sigtimedwait? cette fonction a le même comportement que sigwaitinfo sauf qu'elle rend la main après un temps donné, ce que je ne souhaite pas pour mon programme.

    Mon signal sigusr1 est envoyé dans un autre programme à partir de la primitive kill. Je suis sur qu'il est bien réceptionné par le programme "cible" car ma fonction treatSignal est bien lancé. Pour rappel :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
            void treatSignal(int numero, siginfo_t* info, void* inutile) {
    	printf("signal received from:%d !! \n", info -> si_pid);
            }
     
            void test(void) {
    	struct sigaction action;
    	action.sa_sigaction = treatSignal;
    	[...]
            sigaction(SIGUSR1, & action, NULL);
    	[...]
            }

    J'ai fait un printf de SIGRTMIN, SIGRTMAX et SIGUSR1. J'obtiens 34, 64 et 10. SIGUSR1 n'est donc pas compris entre SIGRTMIN et SIGRTMAX. Qu'est-ce que cela veut-t'il dire?

  9. #9
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    cela veux dire que ce n'est pas un signal tant réel du coup ton flag SA_SIGINFO n'a aucun sens

    soit tu définis ce flag et tu envois un signal compris dans les valeurs définis ou alors c'est un comportement indeterminé

    pour envoyer un signal TR il existe d'autres primitives que kill sig_queue par exemple

    Si la valeur de sa_flags est à SA_SIGINFO, c'est le pointeur de fonction de sa_sigaction qui est pris en compte et non sa_handler. Le problème ne vient donc pas de là.
    tu es sûr de ta source parce que moi justement dans ce cas c'est sa_handler
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juin 2007
    Messages : 106
    Points : 68
    Points
    68
    Par défaut
    Je vais essayer les signaux temps-réels avec sig_queue.

    Pour sa_siginfo, ma source est tout simplement le manpage de sigaction :

    "If SA_SIGINFO is specified in sa_flags, then sa_sigaction (instead of sa_handler) specifies the signal-handling function for signum."

    Merci pour les infos.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juin 2007
    Messages : 106
    Points : 68
    Points
    68
    Par défaut
    Ca marche ! Voici le code pour attendre un signal SIGRTMIN :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	struct sigaction action;
    	action.sa_sigaction = treatSignal;
    	sigemptyset(& action.sa_mask);
    	action.sa_flags = SA_SIGINFO;
    	sigaction(SIGRTMIN, & action, NULL);
     
    	siginfo_t info;
    	sigset_t sigset;
    	sigaddset(&sigset, SIGRTMIN);
    	sigwaitinfo(&sigset, &info);
    et le code pour envoyé le signal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
            union sigval sigVal;
    	sigVal.sival_int = 0;
    	if(sigqueue(args -> pid, SIGRTMIN, sigVal) != 0) {
    		perror("sigqueue error");
    	}
    Merci pour ton aide hegros !

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

Discussions similaires

  1. Communication Inter Processus
    Par pittacos dans le forum Windows
    Réponses: 3
    Dernier message: 29/07/2008, 09h50
  2. [windows] Communication inter-processus
    Par litbos dans le forum Windows
    Réponses: 6
    Dernier message: 16/01/2007, 09h13
  3. [Perl] communication Inter-Processus
    Par MarneusCalgarXP dans le forum Langage
    Réponses: 15
    Dernier message: 14/08/2006, 22h43
  4. [débutant] Communication inter-processus
    Par tooney dans le forum C
    Réponses: 3
    Dernier message: 29/12/2005, 20h48
  5. communication inter-processus
    Par benoit70 dans le forum MFC
    Réponses: 1
    Dernier message: 14/04/2005, 09h55

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