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

前端 未结 8 1113
悲&欢浪女
悲&欢浪女 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: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
    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;
    }
    

提交回复
热议问题