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 :

Threader la fonction d'une classe


Sujet :

C++

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Juin 2012
    Messages : 41
    Points : 41
    Points
    41
    Par défaut Threader la fonction d'une classe
    Bonjour,

    J'essaie actuellement de threader une fonction faisant partie d'une classe.

    Quelques petites informations :

    La classe créée une connexion, reçois des paquets et réagis en conséquence.

    Voici son prototype :
    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
     
    class server
    {
    private :
            char buffer[8000];
            bool starter_check;
            int erreur;
            SOCKET sock;
            SOCKADDR_IN sin;
     
            #if defined (WIN32)
                    WSADATA WSAData;
            #endif
     
            queue<char> fileA;
            handler *framework;
    public :
        //creation de la socket etc
        server(int port, string ip_g);
        // Destruction de la socket etc
        ~server();
        // Boucle d'écoute
        void listener(void *data);
        // Envoie de donnees
        void sendData(char *data_g);
        // Vidage de la queue
        int processQueue();
    Mon code devrais fonctionner de la façon suivante :

    1) Le constructeur créée la socket, puis fait un thread sur la fonction listener
    2) la fonction listener() réceptionne les paquet et les stock dans la variable "fileA" (qui est de type queue<byte>
    3) Pendant ce temps, je lance la fonction processQueue(), qui va peu à peu traiter les paquets et vider la queue


    Malheureusement, le thread ne semble pas accepter ma fonction. En effet, quand je compile mon projet je reçois ce message d'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    server.cpp: In constructor 'server::server(int, std::string)':
    server.cpp:38: error: argument of type 'void* (server::)(void*)' does not match 'void* (*)(void*)'
    Voici le .cpp ( on sait jamais ) :

    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
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
     
    #include "network/server.h"
     
    // ################################################
    // ##
    // ##   Configuration de la socket
    // ##   Connexion
    // ##   Destruction
    // ##
    // ################################################
     
    server::server(int port, string ip_g)
    {
        framework = new handler();
     
            #if defined (WIN32)
                    erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
            #else
                    erreur = 0;
            #endif
     
        if(!erreur)
        {
            // create socket
            sock = socket(AF_INET, SOCK_STREAM, 0);
     
            // Connection configuration
            sin.sin_addr.s_addr = inet_addr(ip_g.c_str());
            sin.sin_family = AF_INET;
            sin.sin_port = htons(port);
            // If connection
            if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
            {
                pthread_t thread;
     
                // Permet d'exécuter le fonction maFonction en parallèle
                pthread_create(&thread, NULL, listener, NULL);
     
                processQueue();
                starter_check = true;
            }
            else
                starter_check = false;
     
        }
        else
            starter_check = false;
    }
     
     
    server::~server()
    {
                closesocket(sock);
     
                #if defined (WIN32)
                        WSACleanup();
                #endif
     
    }
     
    // ################################################
    // ##
    // ##   Creation de la boucle d'écoute
    // ##   Processus de vidage de la queue
    // ##
    // ##
    // ################################################
     
     
    void *server::listener(void *data_g)
    {
        int ok;
        while(true)
        {
            // Reception des données
            ok = recv(sock, buffer, sizeof(buffer), 0);
            // Envoie des données dans la queue ("fileA" étant la queue)
            for(int i = 0;i<ok;i++)
            {
                fileA.push(buffer[i]);
            }
        }
        return NULL;
    }
    void server::sendData(char *data_g)
    {
        int ok = send(sock, data_g, sizeof(data_g), 0);
    }
     
    int server::processQueue()
    {
        while(fileA.size() > 0)
        {
            // Recupération du contenu et vidage de la queue
     
     
        }
        return 0;
    }
    Merci d'avance.

  2. #2

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Juin 2012
    Messages : 41
    Points : 41
    Points
    41
    Par défaut
    Merci de ta réponse Winjerome,

    Mais je reçois toujours une erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    error: invalid conversion from 'DWORD (*)(void*)' to 'void* (*)(void*)'
    error:   initializing argument 3 of 'int pthread_create(pthread_t*, pthread_attr_t_* const*, void* (*)(void*), void*)'
    Je ne vois pas du tout ce que je pourrais faire, une idée ?

  4. #4
    Invité
    Invité(e)
    Par défaut
    Le DWORD de la FAQ n'était qu'un exemple, utilisé car la fonction CreateThread prend un pointeur sur une fonction qui en retourne un.
    Dans ton cas, garde un retour de type void

  5. #5
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Juin 2012
    Messages : 41
    Points : 41
    Points
    41
    Par défaut
    C'était en effet une erreur stupide de ma part

    Mais en rectifiant le code je suis tombé sur le message d'erreur le plus bizarre qui soit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    error: invalid conversion from 'void* (*)(void*)' to 'void* (*)(void*)'
    comment peut-il y avoir une erreur alors que les 2 types sont les mêmes ??!

  6. #6
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Tu devrais appeler ta methode listener depuis la fonction threadee et non pas directement ta methode. Un truc dans le genre :

    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
    void *thread_func(void *c)
    {
      server *s = static_cast<server*>(c);
     
      s->listener();
      return 0;
    }
     
    //constructeur de ta classe
    server::server()
    {
      ...
      pthread_create(&thread, NULL, thread_func, this);
      ...
    }

  7. #7
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Juin 2012
    Messages : 41
    Points : 41
    Points
    41
    Par défaut
    Bonjour,

    Cela a réglé l'erreur du thread Mais un deuxième problème apparait :

    Le programmes arrête de fonctionner quand je le lance et je pense que cela est dû au fait que j'utilise les variables de classe dans ma fonction threadée.

    Ma question est donc : ais-je accès au variables de classe dans ma fonction thread, et si oui, les valeurs seront elles modifiées pour les deux fonction en cours ? (la threadée et la principale, la threadée étant listener() et la principale processQueue()) .

    Merci d'avance .

  8. #8
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Je n'ai pas trop regarde ton code mais je pense que l'erreur vient du fait que tu as des acces concurrents a tes variables membres. Pour eviter ce probleme, utilise les mutex. Sinon oui, tu peux utiliser tes variables membres dans ta fonction thread en appelant une methode de ta classe qui le fera (ce qui me semble etre la meilleure solution).

  9. #9
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Juin 2012
    Messages : 41
    Points : 41
    Points
    41
    Par défaut
    Merci de toute l'aide que vous m'avez tous apporté jusqu'à maintenant.

    Mais ma classe ne semble pas tenir la route, c'est un peu trop expérimental.

    Je vais donc commencer un nouveau sujet pour essayer de découvrir quelle est la meilleur façon de recevoir des paquets.

    Je mettrais le liens ci dessous :

    http://www.developpez.net/forums/d13...aiter-paquets/

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/03/2005, 12h37
  2. Réponses: 4
    Dernier message: 10/02/2005, 16h10
  3. [VB6]Valeurs une collection renvoyée par la fonction d'une classe
    Par jacma dans le forum VB 6 et antérieur
    Réponses: 14
    Dernier message: 30/03/2004, 11h04
  4. Réponses: 4
    Dernier message: 17/03/2004, 17h24
  5. Réponses: 14
    Dernier message: 15/01/2004, 01h15

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