【问题标题】:periodic timer intervals in C++C ++中的定期计时器间隔
【发布时间】:2021-09-10 06:29:52
【问题描述】:

我正在将代码从 C# 转换为 C++。我想每隔一段时间调用一个函数。 我在 C# 中的原始函数是:

private void Init_timerGetData()
{
    timerGetData = new Timer();
    timerGetData.Interval = 5;
    timerGetData.Tick += new EventHandler(ReadData_Tick);
}

private void ReadData_Tick(object sender, EventArgs e)
   {...}

如何在 C++ 中重写这个函数以获得相同的功能?

【问题讨论】:

标签: c# c++ chrono


【解决方案1】:

您可以使用启动thread 来进行调用的类来创建自己的类。这是我使用的一个简单的方法,它将调用每个句点,直到类的析构函数运行。您可以调整实现的细节以实现您想要的大部分内容:

#include <atomic>
#include <chrono>
#include <functional>
#include <thread>

class call_every
{
    std::function<void()> f_;
    std::chrono::system_clock::duration d_;
    std::chrono::system_clock::time_point run_now_;
    std::atomic_bool quit_;
    std::thread thr_;

public:
    ~call_every()
    {
        quit_ = true;
        thr_.join();
    }

    template <class F>
    explicit call_every(F f, std::chrono::system_clock::duration d)
        : f_{std::move(f)}
        , d_{d}
        , run_now_{std::chrono::system_clock::now()}
        , quit_{false}
        , thr_{&call_every::run, this}
        {}

private:
    void run()
    {
        while (!quit_)
        {
            f_();
            run_now_ += d_;
            std::this_thread::sleep_until(run_now_);
        }
    }
};

#include <iostream>

int
main()
{
    using namespace std;
    using namespace std::chrono;
    call_every x{[]{cout << "Hi" << endl;}, 5s};
    this_thread::sleep_for(15s);
}

$ a.out
Hi
Hi
Hi
Hi
$

这是上面的一个变体,它对quit_ 命令的响应性更强。它不是在持续时间内无条件地休眠,而是使用condition_variablewait_until~call_every() 可以在持续时间超时之前中断。这确保了更及时的关闭,如果这很重要的话。

#include <chrono>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <thread>

class call_every
{
    std::mutex mut_;
    std::condition_variable cv_;
    std::function<void()> f_;
    std::chrono::system_clock::duration d_;
    std::chrono::system_clock::time_point run_now_;
    bool quit_;
    std::thread thr_;

public:
    ~call_every()
    {
        {
            std::lock_guard lock{mut_};
            quit_ = true;
        }
        cv_.notify_one();
        thr_.join();
    }

    template <class F>
    explicit call_every(F f, std::chrono::system_clock::duration d)
        : f_{std::move(f)}
        , d_{d}
        , run_now_{std::chrono::system_clock::now()}
        , quit_{false}
        , thr_{&call_every::run, this}
        {
        }

private:
    void run()
    {
        while (true)
        {
            f_();
            run_now_ += d_;
            std::unique_lock lock{mut_};
            if (cv_.wait_until(lock, run_now_, [this]() {return quit_;}))
                break;
        }
    }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 2015-08-14
    相关资源
    最近更新 更多