Probleme avec les threads en C++ sour linux

Signaler
Messages postés
1
Date d'inscription
mardi 6 avril 2004
Statut
Membre
Dernière intervention
15 avril 2004
-
Messages postés
49
Date d'inscription
mercredi 12 février 2003
Statut
Membre
Dernière intervention
5 septembre 2006
-
Bonjour,
j'ai le probleme suivant a regler en C++
je travaille sur les threads sous linux, avec la librairie "pthread"
Lorsque je crée un thread, celui ci doit exectuer une fonction membre d'un classe mais Ce n'est pas ce

point là qui me pose probleme. Le soucis est que cette fonction membre qui doit etre lancé prend en

parametre des attributs d'une autre classe, et me renvoie en fin de triatement un pointeur sur une

classe encore différente, et ce sont ces deux dernieres chose que je ne parvient pas a faire. C'est à

dire que je ne sais pas comment envoyer à ma fonction les parametres en entrée, ni comment recuperer mon

resultat.

Pour appeller ma fonction membre je procede de la maniere suivante :

class pairint{
public:
pairint(int, int);
~pairint() {};
void add();
void printpair();
private:
int _x;
int _y;
};

pairint::pairint(int x, int y) {
_x = x;
_y = y;
};

void pairint::add() {
cout << "sum of pair is "<< _x+_y << "\n";
};

void pairint::printpair() {
cout << "value of x is " << _x << "\n";
cout << "value of y is " << _y << "\n";
};

extern "C" void *ThreadStartup(void *);

int main(int argc, char **argv)
{
pairint *t=NULL;
pthread_t thread;
int rc;

t = new pairint(5,10);

rc = pthread_create(&thread, NULL, ThreadStartup, (void *)t);
if (rc) {
cout << "Failed to create a thread" << "\n";
exit(EXIT_FAILURE);
}

printf("Waiting for thread to complete\n");
rc = pthread_join(thread, NULL);
if (rc) {
cout << "Failed to joint a thread" << "\n";
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}

void *ThreadStartup(void *_tgtObject) {
pairint *tgtObject = (pairint *)_tgtObject;
tgtObject->add();
delete tgtObject;
return (NULL);
}

Ici c'est un exemple simple. Mais ce que je cherche a faire, c'est passer des arguments a la fonction

ThreadStartup qui n'appartiennent pas a la classe "pairint". Et je voudrais aussi recuperer un pointeur

sur une classe en retour.
Voila, si quelqu'un a une idée je le remercie par avance.

1 réponse

Messages postés
49
Date d'inscription
mercredi 12 février 2003
Statut
Membre
Dernière intervention
5 septembre 2006

Bonjour monsieur Benjamvs :) , ca roule ?..bref, c pas le lieu pour tapper la causet' :) .

Alors en fait, ton problème repose sur le principe des membres statiques des classes.
En effet, les fonctions threads doivent être déclarées en tant que membres statiques de classes (car elles ne peuvent pas être instanciées) ou bien en tant que fonction toute bête (dans un header par ex.). Si c'est seulement déclaré en membre normal, ca plantera à la compilation.
Ensuite, le typage de ces fonctions de threads est batard (c du void*), de même, il n'y a qu'un seul paramètre possible qui est aussi en void*. Mais c'est un avantage car tu peux le "caster" en ce que tu veux.

Donc pour revenir à ton exemple, le début est bon pour passer un paramètre à ton thread :
pthread_t thread;
int rc;
pairint *t = new pairint(5,10);
rc = pthread_create(&thread, NULL, ThreadStartup, (void *)t);
if (rc) {
  cout << "Failed to create a thread" << "\n";
  exit(EXIT_FAILURE);
}

Dans ce bout de code, tu transmets par le 4ème paramètre de la fonction pthread_create le paramètre de la fonction de thread "ThreadStartup". D'ailleurs, tu l'as casté en void*, ce qu'il faut faire.

Ensuite, pour récuperer le retour de la fonction, tu es obligé de mettre ton thread en "join", ce qui a pour conséquence de bloquer ton thread parent jusqu'à ce que le thread fils soit terminé. Ca perd beaucoup de l'intérêt des threads si tu veux faire un programme avec des threads travaillant vraiment en //. Enfin toujours est il que c'est le deuxième paramètre de ta fonction pthread_join qui pointera vers ton retour de fonction de thread (là, fo le caster en void**). Pour reprendre ton exemple en le modifiant :
printf("Waiting for thread to complete\n");
CMaClasse* retourThread;
rc = pthread_join(thread, (void**)retourThread);
/* a ce stade, tu peux accéder à retourThread qui pointera sur ta valeur de retour */
-----------
void *ThreadStartup(void *_tgtObject) {
  pairint *tgtObject = (pairint *)_tgtObject;
  tgtObject->add();
  delete tgtObject;
  CMaClasse* retourThread
  return (void*)retourThread;
}


Voilà en gros...mais le mieux, si tu ne veux pas avoir un thread fils bloquant le thread père, tu peux passer par des variables globales (par exemple des variables statiques de classe.aussi). Tu peux d'ailleurs utiliser ce principe pour les paramètres aussi. (j'aime les membres statiques je sais :big) )

Voilà p'tit Ben, et pas trop de Q3 pdt les h de repos :blush)

@+
Jérôme
:shy)