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

Bibliothèques, systèmes et outils C Discussion :

Entrées/Sorties non bloquantes Linux: interrompre ppoll avec un signal


Sujet :

Bibliothèques, systèmes et outils C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2014
    Messages : 51
    Points : 20
    Points
    20
    Par défaut Entrées/Sorties non bloquantes Linux: interrompre ppoll avec un signal
    Bonjour,

    mon application réseau communique sur plusieurs sockets via UDP. L'ensemble des sockets et stoqué dans un tableau de taille fixe mais dont le nombre d'élément et leur position varie au cours du temps (à cause d'ajout ou de suppression dans le tableau).

    J'aimerais lire sur toutes les sockets en même temps, attendant d'un certain message et ce dans le même thread, du coup je pense aux entrée sorties non bloquantes via poll en utilisant un tableau de pollfd de la même structure que mon tableau. Le problèmé étant que la structure du tableau change, il faut donc que poll le prenne en compte, il faudra même le réveiller en cas de changement car poll est bloquant.
    Je viens de découvrir ppoll qui elle prend aussi un sigmask_t de sorte qu'elle soit réveiller en cas de réception de certains signaux, ça devrait faire l'affaire.
    Malheureusement je n'arrive pas à interrompre ppoll...

    Dans le thread de gestion des messages j'ai:

    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
     
      sigset_t mask;
      sigemptyset (&mask);
      sigaddset (&mask, SIGUSR1);
      char buff[513];
      int ret;
     
      while (1) {
        debug("mdiff_manager", "ppoll number %d...", ++count);
        int ret = ppoll(poll_mdiff, nring+1, NULL, &mask);
        if (ret > 0) {
          int found = 0;
          for (int i = 0; i < nring; ++i) {
            if (poll_mdiff[i].revents == POLLIN) {
             found = 1;
              int rec1 = recv(poll_mdiff[i].fd, buff, 512, 0);
              if (rec1 >= 0) {
                buff[rec1] = 0;
                debug("mdiff_manager", "message received: %s", buff);
                if (strcmp(buff, "DOWN"))
                  rm_ring(i);
              }
              else {
                printf"poll_mdiff[%d].revents == POLLIN whereas recv returns %d",
                    i, rec1);
              }
            }
          }
          if (!found) 
            printf("Is it SIGUSR1?");
        }
        else {
         printf("pprol retval: %d", ret);
        }
    Et dans le thread qui modifie la structure du tableau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        int r = pthread_kill(thread->mdiff_manager, SIGUSR1);
    Ou thread->mdiff_manager et le thread de gestion des messages.
    Le résultat de pthread_kill est bien 0, par défaut ce qu'il se passe c'est que le programme quitte à cause du signal SIG_USR1, pourtant il devrait être capté par ppoll.
    J'ai donc ajouté avant la boucle while
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    signal(SIGUSR1, SIG_IGN);
    maintenant le signal est simplement ignoré, mais toujours pas pris en compte par ppoll.

    Je n'ai trouvé aucun exemple sur internet et la documentation ne répond pas à mon problème, si quelqu'un sait comment utiliser ppoll ou a déja rencontré ce problème je lui serais vraiment reconnaissant de bien bien vouloir partager son expérience.
    Merci.

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    1 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 1 254
    Points : 6 096
    Points
    6 096
    Par défaut
    Bonjour,
    Plutôt qu'un SIG_IGN qui va directement effacer le signal, il faut fournir un callback même vide, ainsi le signal n’arrêtera pas l'application et pourra donc être vu.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2014
    Messages : 51
    Points : 20
    Points
    20
    Par défaut
    J'ai ajouté la modif:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    static void signal_handler_empty(int signum)
    {
      return ;
    }
     
    signal(SIGUSR1, signal_handler_empty);
    Mais cela ne permet toujours pas de sortir de ppoll.
    Si j'ai bien compris l'utilité de ppoll, le mask de signaux transmis contient des signaux pour interrompre ppoll et continuer à l'instruction suivante ?
    Je n'arrive pas à obtenir ce comportement pour l'instant...

  4. #4
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    1 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 1 254
    Points : 6 096
    Points
    6 096
    Par défaut
    Je ne connais pas poll() encore moins ppoll(), je connais un peu les signaux.
    La doc indique que ppoll() masque les signaux fournis, il me semble que tu veux l'inverse.
    Pour masquer tous les signaux sauf SIGUSR1, il faut plutôt
    sigset_t mask;
    sigfillset(&mask);
    sigdelset(&mask, SIGUSR1);

    Quand un signal quelconque survient pendant une fonction bloquante, celle ci est immédiatement débloquée, elle retourne une erreur, et errno vaut EINTR.
    Si le signal est sans impact, on peut alors rappeler la fonction!
    Sinon le handler a vraisemblablement positionné un indicateur que l'on utilise pour décider de la suite à donner à cette interruption.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2014
    Messages : 51
    Points : 20
    Points
    20
    Par défaut
    Ok, je croyais que le masque passer contenait des signaux qui serait utiliser pour interrompre ppoll.
    Est-ce qu'il existe alors un moyen de faire des entrées non bloquantes sur un ensemble de socket en gardant la possibilité de modifier l'ensemble des sockets à n'importe quel moment?
    Je ne vois pas comment faire...

  6. #6
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    1 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 1 254
    Points : 6 096
    Points
    6 096
    Par défaut
    A mon avis pour gérer plusieurs sockets il est préférable de mettre en place un pool de threads qui seront chacun à l'écoute d'un socket.
    En utilisant ppoll() qui démasque SIGUSR1 c'est peut être possible.
    Dans tous les cas, la solution n'est pas si simple.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2014
    Messages : 51
    Points : 20
    Points
    20
    Par défaut
    Oui, mon programme est déje hyper threadé donc je voulais éviter ça, et puis utiliser les entrées sorties bloquantes m'aurait apporté de bon point car ça faisait aussi partie du cours (projet d'étude).
    Je trouvais ça élégant de pouvoir utiliser qu'un seul thread pour ça mais bon...

    Si quelqu'un à la solution pour les entrées sorties non-bloquantes je suis preneur

Discussions similaires

  1. Réponses: 1
    Dernier message: 02/05/2013, 10h10
  2. Lecture non bloquante sur plusieurs Sockets avec nio
    Par ratakses dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 19/04/2007, 16h14
  3. Problème de mutex avec Waitforsingleobject non-bloquant
    Par rvzip64 dans le forum API, COM et SDKs
    Réponses: 6
    Dernier message: 03/11/2005, 11h02
  4. [Débutant]Procédure avec paramètres entrée / sortie
    Par jeromejanson dans le forum Langage
    Réponses: 13
    Dernier message: 10/10/2005, 08h30
  5. Réponses: 5
    Dernier message: 02/09/2005, 12h47

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