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 :

[Pthreads/Windows] Problème avec pthread_t


Sujet :

POSIX C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Par défaut [Pthreads/Windows] Problème avec pthread_t
    Bonsoir,

    Voilà un code qui illustre mon problème :
    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
    #include <stdio.h>
     
    #include <pthread.h>
     
    struct s
    {
      pthread_t id;
      void* (*pf) (void*);
    };
     
    static void* f (void* p);
     
    int main (void)
    {
      struct s s1 = {0, f};
     
      s1.pf(NULL);
     
      return 0;
    }
     
    static void* f (void* p)
    {
      (void)p;
     
      puts("test");
     
      return NULL;
    }
    GCC me dit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    forums.c: In function `main':
    forums.c:15: warning: missing braces around initializer
    forums.c:15: warning: (near initialization for `s1.id')
    forums.c:15: warning: initialization makes integer from pointer without a cast
    forums.c:15: warning: missing initializer
    forums.c:15: warning: (near initialization for `s1.pf')
    Visual C 2005 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    forums.c(15) : warning C4047: 'initialisation'*: 'unsigned int' diffère de 'void
     *(__cdecl *)(void *)' dans les niveaux d'indirection
    Et à l'exécution, ça plante. Si dans la structure s1 je remplace le champ pthread_t par un int, aucun problème (à la compilation et à l'exécution).
    Les headers et la bibliothèque pthreads viennent du fichier "pthreads-w32-2-8-0-release.exe" téléchargé sur ce site : http://sourceware.org/pthreads-win32/.
    Est-ce qu'il y a une erreur dans mon code ? J'avoue pour le moment ça m'échappe complètement. Je testerai sur une autre plateforme demain mais ça m'arrangerait de pouvoir utiliser les pthreads sous Windows aussi.

    Merci.

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par dapounet Voir le message
    Voilà un code qui illustre mon problème :
    Ceci fonctionne (en C, évidemment) :
    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
     
    #include <stdio.h>
    #include <pthread.h>
     
    struct s
    {
       pthread_t id;
       void *(*pf) (void *);
    };
     
    static void *f (void *p)
    {
       (void) p;
     
       puts ("test");
     
       return NULL;
    }
     
    int main (void)
    {
       struct s s1 = { {0, 0}, f };
     
       s1.pf (NULL);
     
       return 0;
    }

  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
    Sous WIN32, pthread_t est défini ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct 
    {
        void * p;                   /* Pointer to actual object */
        unsigned int x;             /* Extra information - reuse count etc */
    } ptw32_handle_t;
     
    typedef ptw32_handle_t pthread_t;
    Je conseille d'utiliser une des nouveautés du C99 (puisque tu utilises mingw): les initialiseurs désignés
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct s s1 = {.pf = f};

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Je conseille d'utiliser une des nouveautés du C99 (puisque tu utilises mingw): les initialiseurs désignés
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct s s1 = {pf = f};
    Manque un . :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct s s1 = {.pf = f};
    Mais pour être portable, mieux vaut faire l'initialisation explicitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    {
       struct s s1 = {0};
       s1.pf = f;

  5. #5
    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
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Manque un . :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct s s1 = {.pf = f};
    corrigé.
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Mais pour être portable, mieux vaut faire l'initialisation explicitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    struct s s1 = {0};
    s1.pf = f;
    les initialiseurs désignés sont tous ce qu'il y a de plus standard (C99) donc portable.

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    les initialiseurs désignés sont tous ce qu'il y a de plus standard (C99) donc portable.
    Bah pas sous Visual Studio...

    standard != portable. Ce serait trop simple...

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Est-on sûr que l'initialisation de la structure pthread_t est portable ?
    N'a-t-on pas, normalement, à utiliser une fonction qui fait abstraction de cela ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    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
    Citation Envoyé par Médinoc Voir le message
    Est-on sûr que l'initialisation de la structure pthread_t est portable ?
    N'a-t-on pas, normalement, à utiliser une fonction qui fait abstraction de cela ?
    Effectivement, en théorie le type pthread_t doit être vu comme opaque et initialisé via pthread_create(). Tout autre utilisation n'est pas portable.

  9. #9
    Membre chevronné Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Par défaut
    Bonsoir,

    Citation Envoyé par Emmanuel Delahaye Voir le message
    Ceci fonctionne (en C, évidemment) :
    [...]
    J'ai essayé ça qui a l'air portable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct s s1 = {{0}, f};
    Mais GCC se plaint si j'utilise -Wextra, il abuse non ?
    Finalement je crois que je vais arrêter de toucher moi-même aux pthread_t, ce sera sûrement plus simple.

    Citation Envoyé par nicolas.sitbon Voir le message
    Sous WIN32, pthread_t est défini ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct 
    {
        void * p;                   /* Pointer to actual object */
        unsigned int x;             /* Extra information - reuse count etc */
    } ptw32_handle_t;
     
    typedef ptw32_handle_t pthread_t;
    Je conseille d'utiliser une des nouveautés du C99 (puisque tu utilises mingw): les initialiseurs désignés
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct s s1 = {.pf = f};
    Je préfère utiliser C89 tant que c'est possible. Mais maintenant je sais au moins d'où vient cette syntaxe bizarre.

    Citation Envoyé par Médinoc Voir le message
    Est-on sûr que l'initialisation de la structure pthread_t est portable ?
    N'a-t-on pas, normalement, à utiliser une fonction qui fait abstraction de cela ?
    À ma connaissance la norme n'impose rien pour le type qu'aliase pthread_t. Sous Linux c'est un entier, sous FreeBSD c'est un pointeur vers une structure.
    La seule fonction que j'ai vue dans ce genre-là c'est pthread_equal().

  10. #10
    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
    Citation Envoyé par dapounet Voir le message
    Mais GCC se plaint si j'utilise -Wextra, il abuse non ?
    Il abuse, certe.

    Citation Envoyé par dapounet Voir le message
    Je préfère utiliser C89 tant que c'est possible. Mais maintenant je sais au moins d'où vient cette syntaxe bizarre.
    Bizarre peut être, pratique, certainement.

    Citation Envoyé par dapounet Voir le message
    À ma connaissance la norme n'impose rien pour le type qu'aliase pthread_t. Sous Linux c'est un entier, sous FreeBSD c'est un pointeur vers une structure.
    La seule fonction que j'ai vue dans ce genre-là c'est pthread_equal().
    Pour moi il n'y a aucune raison à aller trifouiller un type opaque. C'est le principe même de l'encapsulation.

  11. #11
    Membre chevronné Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Pour moi il n'y a aucune raison à aller trifouiller un type opaque. C'est le principe même de l'encapsulation.
    Ce serait quand même plus simple si on pouvait être sûr que pthread_t est un pointeur (et ça ne limiterait pas les implémentations), si je n'avais pas compilé mon code sous Windows je ne me serais sûrement jamais rendu compte de ce problème de portabilité.

  12. #12
    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
    IEEE Std 1003.1-2001/Cor 2-2004, item XBD/TC2/D6/26 is applied, adding pthread_t to the list of types that are not required to be arithmetic types, thus allowing pthread_t to be defined as a structure.

Discussions similaires

  1. Windows: problème avec PrintDlg()
    Par edgarjacobs dans le forum Débuter
    Réponses: 13
    Dernier message: 31/12/2014, 08h58
  2. %display %window problème avec %if %then
    Par L0007 dans le forum SAS AF et formulaires
    Réponses: 2
    Dernier message: 24/10/2011, 13h03
  3. [Code::Blocks/Windows]Problème avec les thèmes GTK+
    Par 3alaovic dans le forum GTK+ avec C & C++
    Réponses: 2
    Dernier message: 16/09/2009, 20h02
  4. [Installation] [Windows] Problème avec notepad
    Par kamy86 dans le forum Subversion
    Réponses: 1
    Dernier message: 26/02/2009, 11h42
  5. Service Windows : problème avec état du service
    Par dlayla4 dans le forum Windows Forms
    Réponses: 5
    Dernier message: 23/05/2008, 09h35

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