De base de la minuterie avec std::thread et std::chrono

Je suis en train de mettre en œuvre une base de minuterie avec les méthodes classiques: start() et stop(). Je suis à l'aide de c++11 avec std::thread et std::chrono.

  • Méthode de démarrage. Crée un nouveau thread qui est endormi pour un intervalle donné de temps, puis d'exécuter un std::function. Ce processus est répété tout en un "running" du pavillon est vrai.
  • Méthode Stop. Juste définit la "running" du pavillon de faux.

J'ai créé et a commencé un objet Timer qui montrent "Bonjour!" à chaque seconde, puis avec d'autres thread, j'ai essayer de l'arrêt de la minuterie, mais je ne peux pas. Le chronomètre ne s'arrête jamais.

Je pense que le problème est avec th.join()[*] que s'arrête l'exécution jusqu'à ce que le thread a fini, mais quand j'enlève th.join() de la ligne, évidemment, le programme se termine avant que le compteur commence à compter.

Donc, ma question est comment faire pour exécuter un thread sans arrêt les autres threads?

#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
class Timer
{
thread th;
bool running = false;
public:
typedef std::chrono::milliseconds Interval;
typedef std::function<void(void)> Timeout;
void start(const Interval &interval,
const Timeout &timeout)
{
running = true;
th = thread([=]()
{
while (running == true) {
this_thread::sleep_for(interval);
timeout();
}
});
//[*]
th.join();
}
void stop()
{
running = false;
}
};
int main(void)
{
Timer tHello;
tHello.start(chrono::milliseconds(1000),
[]()
{
cout << "Hello!" << endl;
});
thread th([&]()
{
this_thread::sleep_for(chrono::seconds(2));
tHello.stop();
});
th.join();
return 0;
}

De sortie:

Hello!
Hello!
...
...
...
Hello!
Comme un autre commentaire, dans mon expérience, en essayant de faire de même, à l'aide de condition_variable était plus efficace (parce qu'il a conçu pour ce genre de chose). Cependant, il rend le code moins claire.

OriginalL'auteur Sysyfydev | 2014-02-03

Leave a Reply

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *