need to call a function at periodic time intervals in c++

前端 未结 8 1091
悲&欢浪女
悲&欢浪女 2020-11-30 08:58

I am writing a program in c++ where I need to call a function at periodic time intervals, say every 10ms or so. I\'ve never done anything related to time or clocks in c++, i

相关标签:
8条回答
  • 2020-11-30 09:13

    I made myself an async system. It should not be confused with std::async. Since it is custom made, I have full control over the timeline, so I can add, edit, remove, append, etc tasks. Mainly it runs in a single thread and guarantees safety between context switches, but also has support for multi-thread syncing. Try to make your own async system, from my experience I would say it's worth it

    0 讨论(0)
  • 2020-11-30 09:19

    It depends on what you would be doing on per interval - displaying time/ticker or something else at specific location of screen/form. Or you may need to send regular data to some connected machine (over socket or pipe). Do you really need 10 millisecond precision?

    Depending on requirement, especially the precision requirement, you may have dedicated thread to do 'something', then wait and do same thing again. Or, on Windows, you may use SetTimer that would trigger WM_TIMER event on each interval (it wouldn't require thread). You may also use waitable timer, multimedia timer etc.

    At last, but quite important - Do you need platform and compiler compatibility? Meaning that, which OS you would be using, or you need platform independent? What compiler features you are looking for (C++11, C++14 or pre C++11).

    0 讨论(0)
  • 2020-11-30 09:21

    Sorry, but I didn't find a design simpler than that.

    You could, make a class that owns both a thread, and a weak_ptr to itself, to be a "holder" that the callable can see it safely, because the callable will still exists even if the object is destructed. You don't want a dangling pointer.

    template<typename T>
    struct IntervalRepeater {
        using CallableCopyable = T;
    private:
        weak_ptr<IntervalRepeater<CallableCopyable>> holder;
        std::thread theThread;
    
        IntervalRepeater(unsigned int interval,
                CallableCopyable callable): callable(callable), interval(interval) {}
    
        void thread() {
            weak_ptr<IntervalRepeater<CallableCopyable>> 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<IntervalRepeater<CallableCopyable>> 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<IntervalRepeater<T>> createIntervalRepeater(unsigned int interval,
                CallableCopyable callable) {
            std::shared_ptr<IntervalRepeater<CallableCopyable>> ret =
                    shared_ptr<IntervalRepeater<CallableCopyable>>(
                            new IntervalRepeater<CallableCopyable>(interval, callable));
            ret->holder = ret;
            ret->thread();
    
            return ret;
        }
    
        ~IntervalRepeater() {
            // Detach the thread before it is released.
            theThread.detach();
        }
    
    };
    
    void beginItWaitThenDestruct() {
        auto repeater = IntervalRepeater<function<void()>>::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;
    }
    
    0 讨论(0)
  • 2020-11-30 09:22

    A simple timer can be implemented as follows,

    #include <iostream>
    #include <chrono>
    #include <thread>
    #include <functional>
    
    void timer_start(std::function<void(void)> 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);
    }
    

    This simple solution does not offer a way to stop the timer. The timer will keep running until the program exited.

    0 讨论(0)
  • 2020-11-30 09:28

    You could look into threading:

    Here's a time interval controlled function implemented in C, using pthread.h, it should be a simple port to C++. Executing a function at specific intervals

    0 讨论(0)
  • 2020-11-30 09:32

    This is quite an old post but I found a really easy solution to this and I would like to share it:

    the solution is to

    #include "unistd.h"
    

    and use the function which is included in the above library,

    usleep(int) 
    

    for example this would call a function every 3000 microseconds

    int main() {
    
        int sleep_time = 3000;
        while(true) { 
    
              usleep(sleep_time);
    
              call function;
        }
    
        return 0;
    }
    

    I used it as well for serial and parallel codes and works in both cases!

    0 讨论(0)
提交回复
热议问题