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 :

Thread (pthread) & pointeur générique


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut Thread (pthread) & pointeur générique
    Bonjour,

    J'ai un projet à réaliser avec une autre personne dans le cadre des cours.
    Nous devons reproduire le jeu blokus avec une partie réseau permettant 4 joueurs.
    Nous n'avons ni vu les sockets ni la mise en forme d'interface graphique et encore moins les threads en cours.

    On m'a proposé la bibliothèque winsock2.h pour la partie réseau et pthread.h pour les threads. Nous utiliserons sûrement GTK pour l'interface.

    Quoiqu'il en soit, j'essaye de comprendre un peu comment ça marche. J'ai un problème pour le moment avec les pointeurs génériques. J'ai deux fonctions identiques enfin presque, l'une incrémente de 1 la variable passée par paramètre et l'autre la décrémente.

    la fonction passée en paramètre à la fonction pthread create doit toujours avoir le prototype
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void* fonction(void* data);
    pour éviter les problèmes de compilation dit le manuel. Ce pourquoi mes fonctions sont construites comme telles.

    Je ne comprends pas pourquoi ce satané compilateur me trouve une erreur dans ce que je fais dans mes fonctions.

    Auriez vous une idée ?

    Merci d'avance !


    ERREUR COMPILATEUR
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    C:\Users\NOOB\Desktop\thread\main.c||In function `maFonction1':|
    C:\Users\NOOB\Desktop\thread\main.c|55|warning: dereferencing `void *' pointer|
    C:\Users\NOOB\Desktop\thread\main.c|55|error: invalid use of void expression|
    C:\Users\NOOB\Desktop\thread\main.c||In function `maFonction2':|
    C:\Users\NOOB\Desktop\thread\main.c|61|warning: dereferencing `void *' pointer|
    C:\Users\NOOB\Desktop\thread\main.c|61|error: invalid use of void expression|
    ||=== Build finished: 2 errors, 2 warnings ===|
    CODE
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    // On inclue les fichiers standard et le header pthread.h
    #include <stdlib.h>
    #include <stdio.h>
    #include <pthread.h>
     
    void *maFonction1( void *data );
    void *maFonction2( void *data );
     
    int main()
    {
        /* Déclaration des threads */
        pthread_t thread1;
        pthread_t thread2;
     
        /* */
        int valeur1=0;
        int valeur2=50;
        int r1=0;
        int r2=0;
     
     while ( valeur1 != 50 || valeur2 != 0 )
           {
               printf("\nF1 : %d \nF2 : %d", valeur1, valeur2);
     
               /* Création des threads */
               r1=pthread_create( &thread1, NULL, maFonction1, (void *)&valeur1);
               r2=pthread_create( &thread2, NULL, maFonction2, (void *)&valeur2);
     
               if ( r1 != 0 || r2 != 0 )
                  {
                       perror("pthread_create");
                       return EXIT_FAILURE;
                  }
           }
     
        /* On attend la fin des processuss */
        r1=pthread_join( thread1, NULL );
        r2=pthread_join( thread2, NULL );
     
        if ( r1==0 && r2==0 )
           {
               printf("\n Fin des processus correcte");
           }
     
      else {
               perror("pthread_join");
           }
     
        return EXIT_SUCCESS;
    }
     
     
    void* maFonction1(void* data)
    {
        *data= *(int *)data + 1;
        return NULL;
    }
     
    void* maFonction2(void* data)
    {
        *data= *(int *)data - 1;
        return NULL;
    }

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     *data= *(int *)data + 1;
    Cela vient de la façon dont est évaluée une expression A = B : B est évalué et la valeur obtenue possède alors le type T (ici T est int). Pour faire l'assignation, cette valeur doit être convertie (implicitement ou explicitement par l'opérateur de cast) en le type de l'objet A et si cette conversion est impossible, l'assignation est impossible.

    Si data est void* , le type de *data est indéterminé (ou void si on préfère) et la conversion est impossible.

    Il faut également transtyper data au premier membre (comme au second) pour rétablir son type exact.

  3. #3
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut
    J'ai lu le tutoriel fourni par le site et voilà ça marche mieux en suivant les instructions xD !

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    // On inclue les fichiers standard et le header pthread.h
    #include <stdlib.h>
    #include <stdio.h>
    #include <pthread.h>
     
    void *maFonction1( void *data );
    void *maFonction2( void *data );
     
    int main()
    {
        /* Déclaration des threads */
        pthread_t thread1;
        pthread_t thread2;
     
        /* */
        int valeur1=0;
        int valeur2=50;
        int r1=0;
        int r2=0;
     
        r1=pthread_create( &thread1, NULL, maFonction1, (void *)&valeur1);
        r2=pthread_create( &thread2, NULL, maFonction2, (void *)&valeur2);
     
        printf("\nF1 : %d \nF2 : %d", valeur1, valeur2);
     
        /* Création des threads */
        if ( r1 != 0 || r2 != 0 )
           {
                  perror("pthread_create");
                  return EXIT_FAILURE;
           }
     
        /* On attend la fin des processuss */
        r1=pthread_join( thread1, NULL );
        r2=pthread_join( thread2, NULL );
     
        if ( r1==0 && r2==0 )
           {
               printf("\n Fin des processus correcte");
           }
     
      else {
               perror("pthread_join");
           }
     
        return EXIT_SUCCESS;
    }
     
     
    void* maFonction1(void* data)
    {
     
        while ( *(void **)data <=50 )
              {
                  printf("\nF1 : %d", *(void **)data);
                  *(void **)data= *(void **)data + 1;
                  getchar();
              }
        return NULL;
    }
     
    void* maFonction2(void* data)
    {
        while ( *(void **)data > 0 )
              {
                  printf("\nF2 : %d", *(void **)data);
                  *(void **)data= *(void **)data - 1;
                  getchar();
              }
        return NULL;
    }

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Ce code est tout à fait incorrect et le compilateur aurait dû le signaler :

    1- *(void **)data est du type void*, donc pointeur (sur void)
    cette comparaison entre un entier différent de 0 et un pointeur aurait dû provoquer un warning
    2- Ceci aurait dû être signalé comme erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     .... *(void **)data + 1
     .... *(void **)data - 1;
    On ne peut faire d'arithmétique avec un void* parce que cela implique de connaitre la taille en byte de l'objet pointé.

    3- l'argument des printf est un pointeur et le format %d ne correspond pas à un pointeur.

  5. #5
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut
    Comment faire alors pour comparer la variable void *data afin de l'utiliser dans la fonction, je ne comprends pas.

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Tu dois connaitre son véritable type et ne pas te tromper. Par exemple :
    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
    void* maFonction1(void* data)
    {
        while ( *(int*)data <=50 )
        {
           printf("\nF1 : %d", *(int*)data);
           *(int*)data= *(int*)data + 1;
           getchar();
        }
        return NULL;
    }
    int main(void)
    {
       int val = 12;
       maFonction1(&val);
       return 0;
    }
    Si la fonction doit pouvoir traiter des valeurs de type différents ou si plusieurs données sont nécessaires, utiliser une structure et passer son adresse.
    Par exemple:
    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
    35
    typedef struct
    {
       int type;
       void * data;
    } Data;
     
    void* maFonction1(void* data)
    {
       switch(((Data*)data)->type)
       {
         case 0 : // type int
              {
                 int * val = ((Data*)data)->data;
                 while ( *val <=50 )
                 {
                    printf("\nF1 : %d", *val);
                    *val= *val + 1;
                    getchar();
                  }
                  break;
              }
         //....
       }
        return NULL;
    }
     
    int main(void)
    {
      int val = 12;
      Data data ;
      data.type = 0;   // type int
      data.data =&val;
      maFonction1(&data);
      return 0;
    }

  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par darkwall_37 Voir le message
    On m'a proposé la bibliothèque winsock2.h pour la partie réseau et pthread.h pour les threads. Nous utiliserons sûrement GTK pour l'interface.
    C'est quoi ce mix infect ????

    Winsock2 : sockets natives Windows.
    pthread : interface thread native Linux.
    GTK : API portable.

    Reste cohérent : fais du natif Windows, du natif Linux, ou du portable, mais pas un mélange des trois... Tu t'exposes à un paquet d'emm... et/ou de conflits, en faisant ça.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  8. #8
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    pthread : interface thread native Linux.
    Une implémentation pour windows existe pthreads-w32

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par ssmario2 Voir le message
    Une implémentation pour windows existe pthreads-w32
    Je sais, je l'ai même déjà utilisée. Mais ça ne change pas le fait que ce n'est pas l'interface native Win32 quoi qu'il en soit, alors que WinSock2 EST une interface native.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

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

Discussions similaires

  1. Pointeur générique vers d'autres types d'objets
    Par LapinGarou dans le forum MFC
    Réponses: 11
    Dernier message: 15/09/2006, 16h48
  2. déréférencer un pointeur générique ?
    Par tintin72 dans le forum C
    Réponses: 6
    Dernier message: 23/07/2006, 12h40
  3. Des problemes avec ces threads <pthread.h>
    Par nasamad dans le forum GTK+ avec C & C++
    Réponses: 26
    Dernier message: 07/07/2006, 12h46
  4. Question sur les pointeurs génériques
    Par mikedavem dans le forum C
    Réponses: 16
    Dernier message: 24/05/2006, 11h56
  5. pointeur générique
    Par ghostdog dans le forum C
    Réponses: 14
    Dernier message: 09/11/2005, 15h23

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