besoin d’appeler une fonction à intervalles de temps périodiques en c ++

J’écris un programme en c ++ où je dois appeler une fonction à des intervalles de temps périodiques, toutes les 10 ms environ. Je n’ai jamais fait quoi que ce soit en rapport avec le temps ou les horloges en c ++. S’agit-il d’un problème simple et rapide ou de ceux pour lesquels il n’existe pas de solution simple?

Merci!

    Une simple timer peut être implémentée comme suit,

     #include  #include  #include  #include  void timer_start(std::function func, unsigned int interval) { std::thread([func, interval]() { while (true) { func(); std::this_thread::sleep_for(std::chrono::milliseconds(interval)); } }).detach(); } void do_something() { std::cout << "I am doing something" << std::endl; } int main() { timer_start(do_something, 1000); while(true); } 

    Cette solution simple ne permet pas d’arrêter le chronomètre. La timer continuera à fonctionner jusqu'à la fin du programme.

    Pour compléter la question, le code de @ user534498 peut être facilement adapté pour avoir l’intervalle de tick périodique. Il est juste nécessaire de déterminer le prochain sharepoint temps de début au début de la boucle de thread du minuteur et de sleep_until ce moment après avoir exécuté la fonction.

     #include  #include  #include  #include  void timer_start(std::function func, unsigned int interval) { std::thread([func, interval]() { while (true) { auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval); func(); std::this_thread::sleep_until(x); } }).detach(); } void do_something() { std::cout << "I am doing something" << std::endl; } int main() { timer_start(do_something, 1000); while (true) ; } 

    Vous pouvez regarder dans le filetage:

    Voici une fonction contrôlée par intervalle de temps implémentée en C, utilisant pthread.h, ce devrait être un simple port en C ++. Exécuter une fonction à des intervalles spécifiques

    Cela dépend de ce que vous feriez par intervalle – affichage de l’heure / du ticker ou de quelque chose d’autre à un emplacement spécifique de l’écran / du formulaire. Ou vous devrez peut-être envoyer des données régulières à une machine connectée (via un socket ou un tuyau). Avez-vous vraiment besoin d’une précision de 10 millisecondes?

    En fonction des besoins, en particulier des besoins de précision, vous pouvez avoir un thread dédié pour faire «quelque chose », puis attendre et refaire la même chose. Ou, sous Windows, vous pouvez utiliser SetTimer pour déclencher WM_TIMER événement WM_TIMER à chaque intervalle (cela ne nécessiterait pas de thread). Vous pouvez également utiliser une timer en attente, une timer multimédia, etc.

    Enfin, mais assez important – Avez-vous besoin de la compatibilité de la plate-forme et du compilateur? Cela signifie que, quel système d’exploitation utilisez-vous ou avez-vous besoin d’une plate-forme indépendante? Quelles sont les fonctionnalités du compilateur que vous recherchez (C ++ 11, C ++ 14 ou pré-C ++ 11)?

    Si vous codez avec Visual C ++, vous pouvez append un élément timer au formulaire pour MainForm vous souhaitez appeler une fonction périodique (ici, il est appelé mon formulaire est MainForm et mon timer MainTimer ). Ajoutez un appel à l’événement tick dans les “Evénements”. Le concepteur appenda cette ligne dans votre fichier .h:

     this->MainTimer->Enabled = true; this->MainTimer->Interval = 10; this->MainTimer->Tick += gcnew System::EventHandler(this, &MainForm::MainTimer_Tick); 

    Ensuite, à chaque intervalle (spécifié en ms), l’application appellera cette fonction

     private: System::Void MainTimer_Tick(System::Object^ sender, System::EventArgs^ e) { /// Enter your periodic code there } 

    Désolé, mais je n’ai pas trouvé de design plus simple que cela.

    Vous pourriez faire d’une classe possédant à la fois un thread et un weak_ptr pour lui-même, être un “détenteur” que l’appelable peut voir en toute sécurité, car l’appelable existe toujours, même si l’object est détruit. Vous ne voulez pas un pointeur pendant.

     template struct IntervalRepeater { using CallableCopyable = T; private: weak_ptr> holder; std::thread theThread; IntervalRepeater(unsigned int interval, CallableCopyable callable): callable(callable), interval(interval) {} void thread() { weak_ptr> holder = this->holder; theThread = std::thread([holder](){ // Try to strongify the pointer, to make it survive this loop iteration, // and ensure that this pointer is valid, if not valid, end the loop. while (shared_ptr> ptr = holder.lock()) { auto x = chrono::steady_clock::now() + chrono::milliseconds(ptr->interval); ptr->callable(); this_thread::sleep_until(x); } }); } public: const CallableCopyable callable; const unsigned int interval; static shared_ptr> createIntervalRepeater(unsigned int interval, CallableCopyable callable) { std::shared_ptr> ret = shared_ptr>( new IntervalRepeater(interval, callable)); ret->holder = ret; ret->thread(); return ret; } ~IntervalRepeater() { // Detach the thread before it is released. theThread.detach(); } }; void beginItWaitThenDestruct() { auto repeater = IntervalRepeater>::createIntervalRepeater( 1000, [](){ cout << "A second\n"; }); std::this_thread::sleep_for(std::chrono::milliseconds(3700)); } int main() { beginItWaitThenDestruct(); // Wait for another 2.5 seconds, to test whether there is still an effect of the object // or no. std::this_thread::sleep_for(std::chrono::milliseconds(2500)); return 0; }