C ++ 11: std :: thread dans une classe exécutant un membre de fonction avec initialisation de threads dans le constructeur
Je suis en train d'utiliser std::thread à partir de C++11. Je ne pouvais pas trouver n'importe où si c'est possible d'avoir un std::thread à l'intérieur d'une classe de l'exécution de l'un de ses membres de fonction. Prenons l'exemple ci-dessous...
Dans mon essai (ci-dessous), l'exécution de la fonction().
Je compile avec gcc-4.4 avec -std=c++0x drapeau.
#ifndef RUNNABLE_H
#define RUNNABLE_H
#include <thread>
class Runnable
{
public:
Runnable() : m_stop(false) {m_thread = std::thread(Runnable::run,this); }
virtual ~Runnable() { stop(); }
void stop() { m_stop = false; m_thread.join(); }
protected:
virtual void run() = 0;
bool m_stop;
private:
std::thread m_thread;
};
class myThread : public Runnable{
protected:
void run() { while(!m_stop){ /* do something... */ }; }
};
#endif //RUNNABLE_H
J'obtiens cette erreur et d'autres: même erreur avec et sans le $)
Runnable.h|9|error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, Runnable* const)’|
Lors du passage d'un pointeur.
Runnable.h|9|error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&Runnable::run’|
source d'informationauteur Mooks
Vous devez vous connecter pour publier un commentaire.
Voici un code à ruminer:
Quelques remarques:
m_stop
comme un simplebool
comme vous l'étiez, c'est horriblement insuffisante; lire sur les barrières de la mémoirestd::thread::join
pouvez jeter donc de l'appeler sanstry..catch
à partir d'un destructeur est témérairestd::thread
etstd::atomic<>
sont non-copiable, doncRunnable
devrait être marqué en tant que tel, si pour aucune autre raison que pour éviter C4512 avertissements avec VC++Cette approche est erronée.
Le problème est que, si l'objet est encore en construction, son type n'est pas encore la plupart des dérivés de type, mais le type du constructeur qui est en cours d'exécution. Cela signifie que lorsque vous commencez le thread de l'objet est toujours un
Runnable
et l'appel àrun()
peut être envoyé àRunnable::run()
qui est virtuelle pure, et qui à son tour provoque un comportement indéfini.Pire encore, vous pourriez avoir un faux sentiment de sécurité, comme cela pourrait être le cas que dans certaines circonstances, le thread qui est en cours de démarrage peut prendre assez longtemps pour que le thread en cours pour compléter le
Runnable
constructeur, et entrez lemyThread
objet, auquel cas le nouveau thread exécute la méthode correcte, mais le changement le système sur lequel vous exécutez le programme (nombre différent de carottes, ou de la charge du système, ou de toute autre circonstance) et le programme va se planter dans la production.