std::function带有定时器成员函数的c++

std::function With Member Function For Timer C++

本文关键字:函数 c++ 成员 function std 定时器      更新时间:2023-10-16

我有一个定时器类,我已经设置了能够绑定到使用std::function模板的自由浮动函数。我想修改类,以便能够支持使用自由浮动函数和类成员函数。我知道std::function可以使用std::bind绑定到成员函数,但我不确定如何使用我拥有的代码设置此:

#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <atomic>
namespace Engine {
    template<class return_type,class...arguments>
    class Timer{
        typedef std::function<return_type(arguments...)> _function_t;
    public:
        Timer(size_t interval,bool autoRun,_function_t function,arguments...args){
            _function = function;
            _interval = interval;
            if (autoRun) {
                Enable(args...);
            }
        }
        ~Timer(){
            if (Running()) {
                Disable();
            }
        }
        void Enable(arguments...args){
            if (!Running()) {
                _running=true;
                enable(_interval, _function, args...);
            }
        }
        void Disable(){
            if (Running()) {
                _running=false;
            }
        }
        std::atomic_bool const& Running()const{
            return _running;
        }
    protected:
        void enable(size_t interval,_function_t func,arguments...args){
            _thread =std::thread([&,func,interval,args...](){
                std::chrono::duration<long long,std::nano> inter(interval);
                auto __interval = std::chrono::microseconds(interval);
                auto deadline = std::chrono::steady_clock::now();
                while (_running) {
                    func(args...);
                    std::this_thread::sleep_until(deadline+=__interval);
                }
            });
            _thread.detach();
        }
    protected:
        _function_t _function;
        std::atomic_bool _running;
        size_t _interval;
        std::thread _thread;
    };
}

任何建议都很好。如果我需要澄清什么,请告诉我。

谢谢

要传递成员函数给this,传递一个指向未绑定成员函数(&Engine::SceneManager::Update)的指针,然后第一个参数是指向应该调用该成员的对象的指针(指向SceneManager对象的指针,这是"隐藏的"this指针)。这就是bind的工作方式,因此不需要对代码进行任何更改。作为一种简单的替代方法,传递一个lambda。

http://coliru.stacked-crooked.com/a/7c6335d4f94b9f93(虽然它没有按预期运行,我不知道为什么)


另外,我对你的代码将internal作为size_t的事实感到困惑,然后将其转换为纳秒,然后将其转换为微秒,然后使用它。为什么不从头到尾都用微秒呢?

析构函数有一个竞争条件。Disable应该在线程完成执行之前停止。我没有使用std::thread太多,但我想一个地方开始是if (_thread.is_joinable()) _thread.join();作为其中的一部分,它可能是有用的,让线程一次只睡100ms左右,并定期检查它是否应该关闭。

Enable应该在启动一个新线程之前停止现有线程。更好的做法是重用同一个线程。不幸的是,没有简单的方法可以让现有的线程切换任务,所以最简单的方法是简单地使用Disable,然后保留现有的代码。