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 :

Appel système interrompu


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 32
    Par défaut Appel système interrompu
    Bonjour,

    Je suis occupé à écrire un programme en C et j'ai quelques soucis avec les interactions entre les appels systèmes bloquant (ex:read et write sur des pipes) et des interruptions.

    J'ai un processus maître qui attend des infos de ses fils. Les processus communiquent par pipe. Je reçoit pas mal de signaux également.

    Je protège donc chaque appel à read et write afin de détecter EINTR. Si j'obtiens ce code d'erreur, je recommence.

    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    while((returnvalue=read(monfd[i][0],&buf,sizeof(char)*SIZE_OF_BUF)<0){
        if(errno==EINTR)
            continue;
        else{
             perror("read ne fonctionne pas");
             exit(EXIT_FAILURE);
        }
    }
    Dans les pages de man, il est indiqué que read place errno à EINTR dans le cas où aucune donnée n'a été lue.

    Ce que je souhaiterais savoir, c'est la façon dont se comporte read si celle-ci a commencé mais n'a pas encore lu l'entièreté de mes données.
    Est-ce que je dois également vérifier si j'ai reçu le bon nombre de caractère? Si tel n'est pas le cas, comment faire pour obtenir la suite? J'ai implémenté une forme de protocole de communication et j'écris et lis uniquement des structures sur les pipes.

    Merci d'avance

  2. #2
    Membre émérite Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Par défaut
    Si read a commencé mais n'a pas fini il te renvoi le nombre d'octets déja lu. Donc tu peux faire un truc du style :
    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
     
    char buffer[4012];
    int nb_octets_lu = 0;
    int nb_octets_lu_total = 0;
    while(nb_octets_lu_total != sizeof(buffer))
    {
      nb_octets_lu = read(fd, buffer + nb_octets_lu_total, sizeof(buffer) - nb_octets_lu_total);
      if(nb_octets_lu < 0)
      {
        if(errno==EINTR)
            continue;
        else
        {
             perror("read ne fonctionne pas");
             exit(EXIT_FAILURE);
        }
      }
      else
      {
        nb_octets_lu_total += nb_octets_lu;
      }
    }
    Attention toutefois, ce code peut amener à des boucles infinies selon les cas.

  3. #3
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    La lecture dans un pipe est par défaut bloquante, cela implique deux choses, soit tu n'as aucun rédacteur dans le pipe auquel cas read() te renvoi 0 soit tu as un redacteur, auquel cas read() reçoit les données jusqu'à ce son buffer soit plein (dans ton cas buf) soit tu reçoit moins de données que prévu dans le buffer signe que le redacteur a arrêter d'écrire.
    Donc ne tout ça te fait 3 cas a testé : read() renvoi 0 =pas de redacteur,
    read() renvoi bufsize, soit tu arrêtes la lecture soit tu la relances, et enfin dernier cas, read() renvoi n avec 0<n<bufsize auquel cas c'était ta dernière lecture.
    De plus, pour la gestion des interruptions, il y a 2 possiblités : soit tu interceptes les interruptions avec signal() auquel cas tu peux faire appel à siginterrupt() pour relancer automatiquement ton read(). 2ème possibilité, tu utilises sigaction() auquel que tu mets SA_RESTART dans sa_flags de ta struct action qui relancera aussi automatiquement read().
    Cordialement.

Discussions similaires

  1. Réponses: 1
    Dernier message: 06/12/2006, 20h59
  2. appel système en c sous linux
    Par momoh dans le forum POSIX
    Réponses: 5
    Dernier message: 03/12/2006, 18h34
  3. Réponses: 3
    Dernier message: 20/06/2006, 07h06
  4. [UBUNTU] Ajout nouvel appel système ?
    Par [Margot] dans le forum Ubuntu
    Réponses: 5
    Dernier message: 11/05/2006, 14h11
  5. appel système opendir dans thread
    Par madimane dans le forum POSIX
    Réponses: 2
    Dernier message: 14/04/2006, 05h39

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