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

Threads & Processus C++ Discussion :

Problème de thread sur une méthode d'une classe C++


Sujet :

Threads & Processus C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2013
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 48
    Points : 24
    Points
    24
    Par défaut Problème de thread sur une méthode d'une classe C++
    Bonjour,

    Toujours dans le cadre de mon projet BTS (qui avance bien d'ailleurs au passage ), je dois faire une application multi tâches.
    Grosso modo, cette application doit recevoir des données de deux clients en même temps. Pour cela, j'utilise les threads.
    Après moult recherches, je parviens à les utiliser en C++ normal (non orienté objet) mais ce n'est pas mon but (je dois utiliser la POO pour mon projet).

    Suite à ce succès, j'ai créé une classe Processus contenant une méthode publique chargée de créer un thread à partir d'une autre méthode publique.

    Header :
    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
     
    #pragma once
    #include <pthread.h>
    #include <iostream>
    #include <string>
     
    using namespace std;
     
    class Processus
    {
    	int nbThreads;
    	pthread_t thread1;
    private:
    	int recevoir();
     
    public:
    	Processus(void);
    	~Processus(void);
    	void demarrerThread();
    	void arreterThread();
    	void* fonctionThread();
    	int getThread();
    };
    Méthodes :
    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
     
    #include "StdAfx.h"
    #include "Processus.h"
     
     
    /* Constructeur et destructeur */
     
     
    void Processus::demarrerThread()
    {
    	cout<<"Demarrage des threads"<<endl;
    	int th1 = 0, j1 = 0; // val à 0 pour test
    	if(nbThreads < 2)
    	{
    		void* (*pVoid)(void *);
    		pVoid = (void *(*)(void *)) fonctionThread();
    		th1 = pthread_create(&thread1, NULL, pVoid, NULL);
    		if(th1 == 0) // th1 -> premier thread a créer
    		{
    			//j1 = pthread_join(thread1, NULL); // si j'appelle cette fonction, le programme plante totalement (a cessé de fonctionner)
    			if(j1 == 0)
    			{
    				cout<<"Reception donnees du serveur normal en cours"<<endl;
    			}
    			nbThreads++;
    		}
     
    	}
    }
    void Processus::arreterThread()
    {
    	int c1 = 0;
    	c1 = pthread_cancel(thread1);
    	if(c1 == 0)
    	{
    		cout<<"Thread arreter"<<endl;
    	}
    }
    void* Processus::fonctionThread()
    {
    	cout<<"fonctionThread"<<endl;
    	return NULL;
    }
    Fichier main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include "stdafx.h"
    #include "Processus.h"
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    	Processus process;
    	cout<<"Les threads"<<endl;
    	process.demarrerThread();
    	return 0;
    }
    Dès que j'appelle la méthode demarrerThread, ça plante et j'ai ce message dans la fenêtre de l'application :


    J'ai également un autre cas de figure. Si j'appelle pthread_join dans la méthode demarrerThread(), le programme se fige et m'indique qu'il a cessé de fonctionner.
    J'ai également essayé de threadé une méthode publique à partir du main mais ça plante également.


    Je développe sous Visual Studio 2010 sous Windows Seven.

    Que faire pour résoudre le problème et pour pouvoir threader deux méthodes (soit la même qui sera threadé 2 fois soit deux différentes) ?
    Merci de votre aide.

  2. #2
    Membre actif Avatar de Rewpparo
    Homme Profil pro
    Amateur
    Inscrit en
    Décembre 2005
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Amateur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 170
    Points : 281
    Points
    281
    Par défaut
    pthread_create ne peut utiliser qu'une fonction globale comme point d'entrée d'un thread.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void* (*pVoid)(void *);
    pVoid = (void *(*)(void *)) fonctionThread();
    th1 = pthread_create(&thread1, NULL, pVoid, NULL);
    Tu transforme un chou en carotte, et tu espère en faire des carottes rappées, mais ça reste du chou derrière, donc forcément c'est pas bon. Ton cast sauvage transforme une fonction membre de classe ne prenant aucun paramètre en une fonction globale prenant un paramètre.
    Il faut que fonctionThread soit statique pour que ça marche, ou alors il faut que tu utilises std::bind pour créer une fonction compatible automatiquement. Et elle doit prendre un void* en paramètre, même si tu ne t'en sert pas.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2013
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 48
    Points : 24
    Points
    24
    Par défaut
    Ce "truc" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void* (*pVoid)(void *);
    pVoid = (void *(*)(void *)) fonctionThread();
    est un reste de solution provisoire trouvé sur le net

    Merci pour l'aide, je vais essayé

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2013
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 48
    Points : 24
    Points
    24
    Par défaut
    Bonjour,
    J'ai passé la fonction fonctionThread en static et en privé (je n'ai pas de raison de la rendre accessible).
    J'ai supprimé tout le castage en void * mais VS me souligne la fonction et m'indique : Error : l'argument de type "void *" est incompatible avec le paramètre de type void *(*)(void *).
    Le 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
     
    void Processus::demarrerThread()
    {
    	cout<<"Demarrage des threads"<<endl;
    	int th1 = 0, j1 = 0;
    	if(nbThreads < 2)
    	{
    		void* arg;
    		th1 = pthread_create(&thread1, NULL, fonctionThread(arg), NULL);
    		if(th1 == 0) // th1 -> serveur normal
    		{
    			j1 = pthread_join(thread1, NULL);
    			if(j1 == 0)
    			{
    				cout<<"Reception donnees du serveur normal en cours"<<endl;
    			}
    			nbThreads++;
    		}
     
    	}
    }
    void* Processus::fonctionThread(void * p)
    {
    	cout<<"fonctionThread"<<endl;
    	return NULL;
    }
    L'erreur lors de la génération du projet :
    error C2664: 'pthread_create'*: impossible de convertir le paramètre 3 de 'void *' en 'void *(__cdecl *)(void *)'
    1> La conversion de 'void*' en pointeur vers non 'void' nécessite un cast explicite


    Merci.

  5. #5
    Membre actif Avatar de Rewpparo
    Homme Profil pro
    Amateur
    Inscrit en
    Décembre 2005
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Amateur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 170
    Points : 281
    Points
    281
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    		th1 = pthread_create(&thread1, NULL, fonctionThread(arg), NULL);
    Le prototype de pthread_create est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);
    (source)
    Toi tu passes en argument 3 le résultat de fonctionThread(arg), qui est un void* (le type de retour de fonctionthread). fonctionThread est exécutée dans le thread appelant, pas dans le nouveau thread. Le 3eme argument doit être &fonctionThread
    Le 4eme paramètre est l'argument que tu passes a fonctionThread, c'est a dire arg.

    Cette ligne doit donc etre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    		th1 = pthread_create(&thread1, NULL, &fonctionThread, arg);
    Regarde les mans au lieu de passer des trucs au petit bonheur la chance. La documentation de toutes ces API est disponible sur le net un peu partout. Si tu codes sans comprendre ce que tu fais, tu vas droit dans le mur.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2013
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 48
    Points : 24
    Points
    24
    Par défaut
    Merci de ta réponse.
    J'ai lu les différents tutos que l'on puisse trouver sur le net mais visiblement j'ai dû louper une étape

    Tout fonctionne la fonction est bien threadé

    Merci encore !

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 30/09/2009, 18h42
  2. modifier un élément d'une form dans une méthode d'une autre form
    Par baldebaran dans le forum Windows Forms
    Réponses: 9
    Dernier message: 14/08/2009, 13h59
  3. portée d'une variable dans une fonction dans une méthode
    Par laurentg2003 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/06/2009, 19h05
  4. Réponses: 6
    Dernier message: 20/04/2007, 15h24
  5. "ajouter une méthode dans une méthode"
    Par Zorgloub dans le forum Langage
    Réponses: 1
    Dernier message: 09/04/2006, 12h53

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