Un usage de boost::function dans un appel à boost::thread - C++ - Programmation
Marsh Posté le 28-05-2008 à 11:33:39
boost::thread comme indiqué dans la doc attend une fonction dont le prototype est void (*)(void). Dans ton cas, il faut creer une mini-classe qui encapsule l'appel à ta fonction et qui prend en parametres du constructeurs les aprametres de ta fonction. la ton machin peut pas macher car boost::function(f) a trjrs la même signature que f et ici c'ets pas void()(void).
Marsh Posté le 28-05-2008 à 11:36:52
En effet, je suis aller voir la signature du constructeur et thread attend void fct(void) c'est bizarre comme choix de la part de boost...
Je vais donc faire une encapsulation
Marsh Posté le 28-05-2008 à 11:38:46
non, c'est le seul moyen d'avoir quelque chose de cohérent et qui prends pas 1598408445 lignes de codes. Le fait de forcer à encapsuler le thread et son état dans une classe et à déléguer l'avancement des choses à cette dernière est un bon schéma.
Et pour t'éviter un nouveau poste au sujet des perfs, fait gaffe que les objets thread sont copiés dans le thread group. Donc fait bien gaffe à ce qui se passe dans ton constructeur et ton constructeur de copie.
Marsh Posté le 28-05-2008 à 11:46:16
J'ai du mal comprendre, j'ai mis en dessous la transcription de ton idée...
Si j'encapsule l'appelle de ma fonction, ca donne ca ?
Mais comment tu vois l'appelle à call ?
boost::thread threadGui(&miniClass(parameters)->call); ????
Code :
|
Marsh Posté le 28-05-2008 à 11:50:31
Presque pas en fait
Code :
|
A voir selon comment ton lauchWXThread marche si t'as pas besoin d'un while( ??? ) dans ton operator()()
Marsh Posté le 28-05-2008 à 12:02:19
merci, je pense que ca va m'aider, j'ai encore à dénouer 2 3 trucs
Marsh Posté le 28-05-2008 à 15:24:45
Bonjour,
Dans ce cas là on aurai pas pus utiliser un boost::bind ? et faire :
Code :
|
ça aurait permis de se passer de la classe subsidiaire non ?
Marsh Posté le 28-05-2008 à 16:10:05
Alors, oui, ca marche parfaitement, mais je ne comprend pas du tout pourquoi...
Je fais encore tres mal la distinction entre boost::function (pointeur sur des fonction) et boost::bind (pointeur sur je ne sais quoi)
Marsh Posté le 28-05-2008 à 16:36:25
Ben en fait le boost:function c'est une classe qui encapsule les pointeurs de fonctions. Donc ça s'utilise comme une fonction.
Le boost::bind ça permet de spécialiser une fonction.
dans ton exemple :
Code :
|
Voilà, après je te recommande d'aller voir la doc de boost. Je trouvais qu'elle était plutôt bien faite
Marsh Posté le 28-05-2008 à 17:12:27
Bin faite, c'est là où on n'est pas d'accord, certaines section sont très bien, d'autre n'apportent absolument aucune info... pour les boost::function, je la trouve tres mal faite... ils compliquent l'exemple de départ sans parler d'appel inter class, c'est n'importe quoi... a croire que boost est une librairie C et pas C++... tous leurs exemples sont avec des struct, ils décollent jamais de ca... faut lire entre les lignes, OK, mais quand on est fatigué, c'est dur !!!
Marsh Posté le 28-05-2008 à 17:14:51
pour certains trucs, tu apprends plus avec les exemples du tarball qu'avec la doc.
Marsh Posté le 28-05-2008 à 19:08:32
Oui, c'est vrai que je viens de voir qu'ils ont mis a jour la doc de cette partie et plus aussi clair.
J'avais appris à l'utiliser avec la doc de la version 1.33.1 (qui d'ailleurs est tjs téléchargeable) et c'était super clair.
Je te conseillerai d'aller la voir car j'ai vu que tu posais pas mal de questions sur boost::function / bind / signal et dans la doc de la version 1.33.1 j'avais vraiment trouvé mon bonheur
Marsh Posté le 30-05-2008 à 10:00:15
J'ai transcrit pour essai cet exemple : http://www.boost.org/doc/libs/1_35 [...] ondvar_ref
Et je me demande vraiment à quoi sert leur variable data_ready.... elle n'est jamais passé à false... elle ne sert à rien à mes yeux...
Code :
|
Marsh Posté le 30-05-2008 à 16:12:59
Comment faire un wait / notify avec boost thread, ce que j'ai ecrit ci dessus ne fait pas du tout ce que je veux... moi je veux un wait notify à la Java....
wait = unlock, j'attend un peu, lock
notify = je reveille les lock immédiatement
Et normalement, ca se lance sur un mutex... mais là (ces cons là) ils le lancent sur un boost::condition... comment ca marche ce truc
Marsh Posté le 09-07-2008 à 09:06:40
PROBLEME DE THREADS, LE RETOUR
J'ai une class singleton (pas le singleton de boost, je l'ai codé moi-même) et donc, il faut l'appeler avec MaClass::getInstance() et là dedans, je souhaite lancer dans un thread une de ses méthodes ( MaClass::launchEventLoop() )
Pour faire ce thread, je souhaite utiliser boost::thread
Je maitrise la technique pour lancer une méthode de class : boost::thread(boost::bind (MaClass::maMethode , arg1, arg2 )) ;
Par contre, ca commence à legerement se corser lorsqu'il s'agit de lancer cela en ayant récupéré l'instance de singleton avant...
Est ce que vous savez faire.... je suis sur une piste (surement mauvaise) avec boost::ref
Marsh Posté le 09-07-2008 à 10:28:40
La ce qu'il me faudrait, c'est un tutoriel où on aborderai les usages croisés de :
boost::thread
boost::ref
boost::bind
boost::function
parce que bon, merci les doc boost, mais c bon pour déposer un brevet, pas pour expliquer comment ca marche !!!!
Marsh Posté le 09-07-2008 à 10:36:40
Alors, j'ai un programme deja complet travaillant en evenementiel (Downloader - Core - GUI ), mais je souhaite déplacer une de mes classes (la classe principale de download) en element threadé
C'est la toute première de mes classes sur laquelle je rencontre mon problème, j'explique :
J'ai une classe abstraite de laquelle j'hérite avec quasiment toutes mes autres classes (le Core, le GUI, et maintenant Downloader) : Singleton :
Code :
|
Elle me permet d'avoir une seule instance de classe, je les appelle comme ca : MaClasse::getInstance()->etc
C'est là que se situe le probleme.
J'ai la classe Downloader dont je parlait : qui devra avoir la signature suivante :
class Downloader: public Singleton<Downloader>, public EventHandler
La classe EventHandler a une methode void runEventLoop(long timeoutMs = 100L); qui lance la lecture en boucle d'une liste d'evemenents.
Pour que ca marche, il faut que runEventLoop soit lancé dans un thread independant.
Hors, je rappelle que Downloader est aussi un singleton...
Je n'arrive pas à faire l'appel dans Boost::thread de ma methode runEventLoop tout en établissant bien le lien sur mon objet unique (siingleton) via Downloader::getInstance()
En fait, je pense faire cette création de thread dans le constructeur de Downloader... c'est surement pas là qu'il faut le faire... que me conseilles tu ?
-----
Voici la forme batarde de ce que ca devrait faire :
boost::thread(Downloader::getInstance()->runEventLoop(100L));
Evidement, ca compile pas ca...
J'ai un peu tenté des trucs avec boost::function, boost::bind boost::ref.... ya surement un arrangement à trouver, mais je ne l'ai pas encore trouvé
Marsh Posté le 09-07-2008 à 11:22:48
boost::thread attends un boost::function ou un type équivalent.
Downloader::getInstance()->runEventLoop(100L) c'est pas un pointeur de fonction ni un boost::function, c'est du type de retour de runEventLoop.
Ce que tu veux faire c'est un truc genre :
boost::thread( boost::bind(&Downloader::runEventLoop, 100L) );
et ça devrait marcher car bind renvoie un objet function correct.
Essaye et dis moi.
La page a lire pour se depatouiller de bidn :
http://www.boost.org/doc/libs/1_35 [...] leshooting
Marsh Posté le 09-07-2008 à 15:52:59
Avec :
boost::thread( boost::bind(&Downloader::runEventLoop, 100L) );
J'ai droit à ca :
1>Compiling... |
et avec :
boost::thread( boost::bind(&Downloader::runEventLoop, _1, 100L) );
J'ai droit à ca :
Downloader.cpp |
Marsh Posté le 09-07-2008 à 16:55:20
Je veux dire, si je lance une autre fonction en thread, ca marche très bien, mais là, c'est une méthode hérité (non virtuelle) de EventHandler, et ca foire surement pour ca !
Marche très bien :
boost::thread( boost::bind(Downloader::getLink, url) );
Boost::thread n'aime-t-il pas les héritages ?
Là franchement, ca commence à me gaver, c'est comme si on faisait du C++ sans avoir droit à l'heritage !!!! Le comble.
Marsh Posté le 10-07-2008 à 14:45:41
Bon, je suis pas un rat, je vais montrer la syntax qui a marché dans mon cas :
Code :
|
=============================
Maintenant, je voudrais poser une question concernant Boost::tuple, ca avait l'air génial sur le papier, mais ca chie dans la colle en pratique,
J'essaye d'ecrire dans une champ avec la syntaxe : monTuple.get<1> = maValeur ; mais ca marche pas !!!!
voici une sequence de code, où la valeur n'est pas modifiée :
Code :
|
Marsh Posté le 10-07-2008 à 18:12:14
.get<I> marche mal sous visual, utilsie :
get<1>(monTuple);
Marsh Posté le 28-05-2008 à 11:26:02
Bonjour,
Voici ce que je cherche à faire : créer un thread BOOST à partir d'une fonction (globale) qui prend des paramètres
J'ai penser à utiliser boost::function, mais sans reussir, et bien, sur l'appel d'une reference sur fonction qui prend des parametres ne marche pas en entrée du constructeur de boost::thread...
Message édité par NounouRs le 28-05-2008 à 11:32:58