繁体   English   中英

Linux C ++ Timer定期回调

[英]linux c++ timer periodic callback

我正在尝试编写一个简单的程序,该程序在其主循环内根据用户输入调用不同的功能(这里没有问题),并且还要自行执行一些操作-这些操作是基于时间的。 因为我想避免潜在的数据访问问题(我不擅长多线程),所以我试图使用回调来确保程序的各个自治部分每隔大约毫秒被调用一次。

根据我的发现,boost :: asio看起来很可行-但是我不知道这里正确的方法是什么。 我编写了一个简单的代码,可以正常工作:

#include <iostream>

#include <boost/asio.hpp>//scheduling
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace std;

void clb(const boost::system::error_code&){
    //  eye.procFrame(&img, true);
    cout << "callback ok" << endl;
}
int main() {
    bool run = true;
    int i =0;

    while(run){
        boost::asio::io_service io;
        boost::asio::deadline_timer t(io, boost::posix_time::seconds(2));
        t.async_wait(clb);
        io.run();
        if(++i>10) run = false;
    }
    cout << "done, i=" << i;
    return 0;
}

我主要关心的是声明-如果将它们移到while循环之外,则回调仅发生一次。 有没有办法编写类似于微控制器定时器中断的回调?

睡眠不是解决方案-它将使程序无响应,并且不能保证程序的各个部分根据其计划进行更新(例如GUI可以每25ms更新一次,但是图像捕获应该每秒仅发生10次[100ms]期间),因为这项繁重的工作占用了大量资源]

也许有一种完全不同的方法会更好? 我当时在考虑更多的线程,但是我担心如果我尝试对每个程序进行线程化,最终都会得到一碗意粉,从长远来看,这是我永远无法管理的。

如果您希望您的计时器反复触发,您可以在计时器回调中仅调用deadline_timer::expires_from_nowdeadline_timer::async_wait 这将使计时器在每次触发时重新安排自身的时间。

计时器与io_service对象相关联,该对象应在一个或多个线程上运行。 您可以将任意数量的计时器与单个io_service关联。 如果您希望您的计时器按顺序执行,而不用担心并发问题,那么只需让一个线程运行io_service

在此示例中,我有一个线程通过两个计时器运行一个io_service。

#include <iostream>
#include <boost/asio.hpp>
#include <boost/chrono.hpp>

boost::asio::io_service io;
boost::asio::deadline_timer timerA(io);
boost::asio::deadline_timer timerB(io);
boost::chrono::steady_clock::time_point appStart;

void onTimerA(const boost::system::error_code& error)
{
    assert(!error);
    std::cout << "A fired at " << 
        boost::chrono::duration_cast<boost::chrono::milliseconds>
        (boost::chrono::steady_clock::now() - appStart).count() 
        << std::endl;

    timerA.expires_from_now(boost::posix_time::seconds(1));
    timerA.async_wait(onTimerA);
}

void onTimerB(const boost::system::error_code& error)
{
    assert(!error);
    std::cout << "B fired at " << 
        boost::chrono::duration_cast<boost::chrono::milliseconds>
        (boost::chrono::steady_clock::now() - appStart).count() 
        << std::endl;

    timerB.expires_from_now(boost::posix_time::seconds(2));
    timerB.async_wait(onTimerB);
}

int main()
{
     // Prevents io.run() from returning.
    boost::asio::io_service::work work(io);

    appStart = boost::chrono::steady_clock::now();

    timerA.expires_from_now(boost::posix_time::seconds(1));
    timerA.async_wait(onTimerA);

    timerB.expires_from_now(boost::posix_time::seconds(2));
    timerB.async_wait(onTimerB);

    io.run();
}

但是,拥有一个线程的弊端是,如果其中一个计时器回调需要花费很长时间才能执行,它将阻塞应该触发的其他计时器,直到完成。 如果您知道您的计时器回调不会花费很长时间,那么可以使用一个线程。

例如,如果您的计时器A间隔为25毫秒,而计时器B间隔为50毫秒,则有时会安排两个计时器同时触发。 其中一个将首先执行,另一个将等待该执行完成,然后自行执行。

如果确实希望计时器回调花费很长时间,并且您无法让计时器等待其他计时器的回调完成,则需要其他线程来运行io_service

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM