benjamvs
Messages postés1Date d'inscriptionmardi 6 avril 2004StatutMembreDernière intervention15 avril 2004
-
15 avril 2004 à 17:29
jsonor
Messages postés49Date d'inscriptionmercredi 12 février 2003StatutMembreDernière intervention 5 septembre 2006
-
17 avril 2004 à 01:54
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;
};
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);
}
jsonor
Messages postés49Date d'inscriptionmercredi 12 février 2003StatutMembreDernière intervention 5 septembre 2006 17 avril 2004 à 01:54
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)