Se connecter / S'enregistrer
Votre question

Problème avec pthread, cpp

Tags :
  • Thread
  • Programmation
Dernière réponse : dans Programmation
31 Mai 2008 20:15:58

Bonjours

Ne trouvant pas beaucoup de tuto sur pthread il y a une juste que je ne comprend pas.

J'ai une fonction qui demande des arguments mais je n'arrive pas à utiliser pthread_create() tout en faisant passer ces arguments. Comment faire pour les faire passer pour que la fonction qui tournera en parallel puisse avoir les variables dont elle a besoin ?

Merci

Autres pages sur : probleme pthread cpp

1 Juin 2008 02:03:44

int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);

il te faut un fonction du type void f(void* arg) qui fera l'appel à ta fonction
tu passes les paramètres à f, dans une structure
1 Juin 2008 12:47:06

J'ai pas tout compris mais de ce que j'ai compris c'est que ma fonction doit être dans ec style

fonction (void* arg)
{
action de la fonction
}

Les arguments dont la fonction a besoin se trouveront dans une structure. Ce que je n'ai pas compris c'est ou est-ce qu'on donne la structure ? à la place de arg (dans ce cas) ?
a b L Programmation
1 Juin 2008 14:18:40

La fonction doit retourner un void*.
Quand tu fais le pthread_create, un paramètre est le pointeur de fonction du thread (3ème paramètre), et le paramètre suivant est le paramètre de la fonction (la structure de données que tu envoies à la fonction en 3ème paramètre).
Dans ta fonction, tu n'a qu'un pointeur en paramètre, mais comme tu sais la structure que tu as envoyé, il te suffit de faire un cast qui va bien.
exemple: http://www.cs.ucsb.edu/~tyang/class/pthreads/code_sgi/p_hello.c
1 Juin 2008 19:36:14

J'ai à peu près compris le principe mais il me reste un point à éclaircir:
lors de la compilation j'obtient l'erreur de compilation:

Citation :
error: `void*' is not a pointer-to-object type


Voila comment je fait:

  1. pthread_create (&thread, NULL, maFonction, (void*)nombre);


(nombre est un pointeur). Et la fonction:
  1. void* maFonction(void* nombre)
  2. {
  3. std::cout << *nombre;
  4. }
a b L Programmation
1 Juin 2008 21:06:22

Comment est ta déclaration de "nombre" ?

la conversion dans le pthread_create n'est pas obligatoire, car tu y met un pointeur, et donc la conversion d'un pointeur typé vers un pointeur non typé peut être implicite.
Par contre, dans ta fonction, il faut que tu convertisses explicitement du pointeur non typé en paramètre vers le pointeur typé de même type que le type à l'appel (car en C c'est un simple mapping sur la mémoire).
1 Juin 2008 22:05:43

nombre est déclaré comme ca:
  1. int nom = 5;
  2. int *nombre = &nom;


Pour le reste si j'ai bien compris, un pointeur typé est un pointeur de type int,char,..... alors que le non typé est un void. C'est bien ca ?

Ensuite pour la convertion dans la fonction il faut que je convertisse le void en int ? ((int*)*nombre) ?

Une autre question, j'arrive à avoir la valeur de nombre mais le problème est qu'elle s'affiche comme ca: 0x5.


Edit: Concernant mon 0x5 c'est résolu. J'ai fait

  1. int* nombre2 = (int*)nombre; std::cout << *nombre;


et ca s'affiche correctement.

J'ai encore une question (ca en fait beaucoup ^^)


  1. //j'utilise des exemples
  2. struct Exemple
  3. {
  4. int nombre;
  5. };
  6. Exemple exemple;
  7. exemple->nombre = 4;
  8. pthread_create (&thread, NULL, fonction, (void*)exemple);


Est-ce qu'il faut bien faire comme ca pour encoyer tout mes parametres à ma fonction ?
a b L Programmation
2 Juin 2008 20:18:55

Citation :
Pour le reste si j'ai bien compris, un pointeur typé est un pointeur de type int,char,..... alors que le non typé est un void. C'est bien ca ?
Oui

Citation :
Ensuite pour la convertion dans la fonction il faut que je convertisse le void en int ? ((int*)*nombre) ?
Oui mais pas comme ça.
La syntaxe correcte est ((int *) nombre), car nombre est un pointeur donc une adresse que tu convertis en adresse.
En faisant * nombre tu prenais le contenu pointé à l'adresse nombre. Tu convertissais donc une valeur en pointeur. En pratique, lors de l'exécution, si nombre est l'adresse 0xa0001234, *nombre va lire la valeur en mémoire à l'adresse 0xa0001234, et c'est 0x00000005. En suite tu convertis ça en pointeur (int*). Donc tu prends l'adresse 0x00000005 en pointeur, et cette adresse est complètement en dehors de ton processus, donc, lorsque tu vas lire (*nombre2), tu auras un crash OS (du genre Read Adress Error 0x00000005... bla bla bla...).

Citation :
Edit: Concernant mon 0x5 c'est résolu. J'ai fait

Ta correction est exacte (j'aurais du tout lire avant d'écrire :)  ).

Concernant ta question, déjà la déclaration de ta variable ce fait comme ceci:
  1. struct Exemple exemple;

si tu veux éviter le "strust", il faut définir un nouveau type:
  1. typedef struct Exemple
  2. {
  3. int nombre
  4. } tExemple;

alors "struct Exemple exemple" est équivalent à "tExemple exemple".

les structures, il faut les voir comme des types de base. Donc, de la même manière que tu as fait ceci:
  1. int nom = 5;
  2. int *nombre = &nom;

tu peux faire la même chose:
  1. tExemple exemple = {4};
  2. tExemple * pExemple = &exemple;

"pExemple" est donc bien un pointeur et pas une valeur comme "exemple". Dans pthread_create, on ne fournit qu'un pointeur, car on ne fournit qu'une adresse mémoire (prenant toujours 4 octets sur les PC classiques).

Dans la fonction, même chose que pour un int:
  1. tExemple * pExemple2 = (tExemple *)pParametre;

2 Juin 2008 20:41:56

C'est vraiment très bien expliqué, Merci.

Je n'ai plus que 1 problème :( 

quand ma fonction est comme suis:

  1. void fonction(void* argument)


je n'ai que 1 erreur de convertion, normal c'est censé être comme suis:
  1. void* fonction(void* argument)


Mais si je fait comme ca, lors de la compilation ca ne prend pas en compte les includes,..... . Je me retrouve donc avec des problème de cout non déclaré et autre. Pourquoi ? et comment résoudre le problème ?
a b L Programmation
2 Juin 2008 22:58:49

Tu n'a qu'une erreur, mais tu as aussi les autre erreurs.

As-tu bien mis ceci:
  1. #include <iostream>

(sans .h)

As-tu bien nommé ton fichier en .cpp ? (la plupart des compilateur font la distinction sur l'extension du fichier: compilation C avec .c et compilation C++ avec .cpp)

utilises-tu bien le std:: avant le cout ? (autre possibilité, mettre "using namespace std;" après les includes)

si tout est bon, montre l'erreur et la ligne de code qui provoque l'erreur (ainsi que la ligne précédente)
2 Juin 2008 23:10:12

Tout est bon ^^

Donc j'ai mon main.cpp ou je peux faire cout, cin, etc..... c'est ok. Après quand je déclare ma fonction comme ca :
  1. void fonction(void* argument)
j'ai juste 2 erreurs de compilation dans pthread_create ().
Citation :
error: invalid conversion from `void (*)(void*)' to `void*(*)(void*)'|
et
Citation :
error: initializing argument 3 of `int pthread_create(pthread_t*, pthread_attr_t_* const*, void*(*)(void*), void*)'|


  1. pthread_create (&thread, NULL, fonction, (void*)ptest);


  1. void fonction(void* ptest);


Par contre quand je met

  1. void* fonction(void* ptest);


J'ai droit à plein d'erreur dans mon fonction.cpp (et non mon main.cpp) comme quoi cout n'est pas définie,......etc....
a b L Programmation
3 Juin 2008 19:58:18

La fonction doit retourner void*, donc tu corrige les erreur de conversion.
Les autres erreurs n'ont aucun rapport avec ça (le compilateur a certainement arrêté la compilation sur l'erreur de conversion), alors montre-les (surtout la première), en montrant la ligne de code qui correspond.
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS