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 :

Problème pthread_cancel et printf


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut Problème pthread_cancel et printf
    Bonjour,

    Je débute en threads C, et j'ai un petit problème d'annulation de threads.
    Code C : 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
    #include <stdio.h>
    #include <unistd.h>
    #include <pthread.h>
     
    void * my_routine(void *arg) {
      int i;
      for (i = 0; i < 10; i++) {
        printf("%d\n", i);
      }
      return NULL;
    }
     
    int main(int argc, char *argv[]) {
      pthread_t thread;
      int ret = pthread_create(&thread, NULL, my_routine, NULL);
      usleep(20);
      pthread_cancel(thread);
      pthread_join(thread, NULL);
      return 0;
    }

    De temps en temps, le printf n'affiche pas la bonne valeur au moment de l'annulation :
    Comment l'éviter ?

    pthread_cancel serait-il l'équivalent de Thread.stop() en Java : il ne faut jamais l'utiliser ?

  2. #2
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Bonjour,

    ça me semble plus être un problème au niveau du printf utilisé dans un environnement multi-thread, mais je n'en suis pas certain, quelque chose du genre le cancel arrive en plein milieu du printf ...

    sinon en ce qui concerne ton code, juste quelques remarques :

    int main(char *argv[]) { n'est pas correct. Si tu n'utilises pas les arguments passés en ligne de commande int main(void) {, ou si tu les utilises int main(int argc, char *argv[]) {. tu fais du java toi

    int ret = pthread_create(&thread, NULL, my_routine, NULL); c'est toujours mieux de vérifier la valeur de retour de ce genre d'appel et gérer les erreurs éventuelles.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void * my_routine(void *arg) {
      int i;
      for (i = 0; i < 10; i++) {
        printf("%d\n", i);
      }
    }
    Cette fonction doit retourner une valeur et aucun return ... le comportement de ton programme n'est pas défini dans ce cas. Ici tu peux simplement rajouter un return NULL;.

    Je ne connais pas les problèmes liés à l'utilisation de Thread.stop() en java, mais avec les pthreads il n'y a, a priori, pas de problèmes pour utiliser pthread_cancel ... peut-être des détails (comme tous les threads ne sont pas interruptibles) mais ils sont documentés dans la man page.

  3. #3
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par kwariz Voir le message
    int main(char *argv[]) { n'est pas correct. Si tu n'utilises pas les arguments passés en ligne de commande int main(void) {, ou si tu les utilises int main(int argc, char *argv[]) {. tu fais du java toi
    Oui, faute d'inattention, j'ai oublié le argc, normalement je mets argc et argv. Je ne savais pas qu'on pouvait mettre int main(void) (par contre je savais qu'on pouvait mettre int main() en C k&r). J'ai corrigé.

    Citation Envoyé par kwariz Voir le message
    int ret = pthread_create(&thread, NULL, my_routine, NULL); c'est toujours mieux de vérifier la valeur de retour de ce genre d'appel et gérer les erreurs éventuelles.
    Tout-à-fait. Mais pour un bête code de test, la flemme ^^

  4. #4
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    J'ai ajouté un usleep(500000) (500ms) à la fin. Ainsi, on peut voir que le numéro dupliqué est affiché après la pause, comme si quelque chose restait quelque part après l'annulation du printf, et qu'il était flushé à la fin…

    Code c : 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
    #include <stdio.h>
    #include <unistd.h>
    #include <pthread.h>
     
    void * my_routine(void *arg) {
      int i;
      for (i = 0; i < 10; i++) {
        printf("%d\n", i);
      }
      return NULL;
    }
     
    int main(void) {
      pthread_t thread;
      int ret = pthread_create(&thread, NULL, my_routine, NULL);
      usleep(20);
      pthread_cancel(thread);
      pthread_join(thread, NULL);
      usleep(500000);
      return 0;
    }

  5. #5
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Oui, ce «bug» provient du fait que tu interromps printff en plein milieu de son boulot.
    Essaye par exemple dans ta boucle for de rendre ton printf insensibles aux interruptions et d'ajouter un [codeinline]usleep[codeinline] pour ralentir le tout et avoir*un point où on peut traiter le cancel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void * my_routine(void *arg) {
      int i;
      for (i = 0; i < 1000; i++) {
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
        printf("%d\n", i);
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
        usleep(2);
      }
     
      return NULL;
    }
    Rallonge aussi le usleep du main.

  6. #6
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Je comprends bien, mais pourquoi printf est-il un cancellation point s'il ne faut pas l'utiliser tel quel même quand le canceltype du thread est PTHREAD_CANCEL_DEFERRED?

Discussions similaires

  1. ProbLème avec fonction printf
    Par snipre dans le forum Langage
    Réponses: 2
    Dernier message: 08/01/2009, 13h20
  2. Problème d'affichage - printf
    Par helio500 dans le forum Débuter
    Réponses: 2
    Dernier message: 02/09/2008, 21h25
  3. Problème sur utilisation printf
    Par xxxvanouxxx dans le forum Linux
    Réponses: 6
    Dernier message: 08/08/2008, 23h33
  4. problème d'affichage avec printf
    Par sorari dans le forum C++
    Réponses: 12
    Dernier message: 08/03/2005, 18h30
  5. Problème a l'affichage dans la console (printf)
    Par PhoneKilleR dans le forum C
    Réponses: 21
    Dernier message: 23/09/2003, 17h21

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