necesidad de llamar a una función en intervalos de tiempo periódicos en c ++

Estoy escribiendo un progtwig en C ++ donde necesito llamar a una función en intervalos de tiempo periódicos, digamos cada 10 ms o menos. Nunca he hecho nada relacionado con el tiempo o los relojes en c ++, ¿es este un problema fácil y rápido o uno de esos en los que no existe una solución ordenada?

¡Gracias!

Un temporizador simple se puede implementar de la siguiente manera:

 #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); } 

Esta solución simple no ofrece una forma de detener el temporizador. El temporizador seguirá funcionando hasta que el progtwig salga.

Para completar la pregunta, el código de @ user534498 se puede adaptar fácilmente para tener el intervalo de marcación periódica. Solo es necesario para determinar el siguiente punto de inicio de tiempo al comienzo del ciclo del hilo del temporizador y sleep_until ese punto de tiempo después de ejecutar la función.

 #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) ; } 

Podrías mirar en el enhebrado:

Aquí hay una función controlada por intervalo de tiempo implementada en C, usando pthread.h, debería ser un puerto simple para C ++. Ejecutando una función en intervalos específicos

Depende de lo que haría en cada intervalo: mostrar el tiempo / ticker u otra cosa en la ubicación específica de la pantalla / formulario. O puede necesitar enviar datos regulares a alguna máquina conectada (a través de un zócalo o tubería). ¿Realmente necesitas una precisión de 10 milisegundos?

Dependiendo de los requisitos, especialmente del requisito de precisión, puede tener un hilo dedicado para hacer ‘algo ‘, luego espere y vuelva a hacer lo mismo. O bien, en Windows, puede usar SetTimer que SetTimer evento WM_TIMER en cada intervalo (no requeriría hilo). También puede usar el temporizador waitable, el temporizador multimedia, etc.

Por fin, pero bastante importante: ¿necesitas compatibilidad con la plataforma y el comstackdor? Es decir, ¿qué sistema operativo usarías o necesitas una plataforma independiente? Qué características del comstackdor estás buscando (C ++ 11, C ++ 14 o pre C ++ 11).

Si está codificando con Visual C ++, puede agregar un elemento de temporizador al formulario que desea llamar a una función periódica (aquí se llama mi formulario es MainForm y mi temporizador MainTimer ). Agregue una llamada al evento tick en los “Eventos”. El diseñador agregará dicha línea en su archivo .h:

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

Luego, en cada intervalo (especificado en ms), la aplicación llamará a esta función

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

Lo siento, pero no encontré un diseño más simple que eso.

Podría hacer una clase que posea tanto un subproceso como un weak_ptr para sí mismo, para ser un “titular” que el invocable pueda ver de forma segura, porque el invocable seguirá existiendo incluso si el objeto se destruye. No quieres un puntero colgante.

 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; }