当前位置: 首页 > 工具软件 > Asio > 使用案例 >

基于Asio 的定时器( asio::steady_timer )

姬烨磊
2023-12-01

    Asio是“异步 IO操作”。asio::steady_timer是定时器。

1. io_context

  io_context对象为异步IO对象提供核心功能。每个 Asio 程序都至少有一个 io_context对象。

     run()是一个阻塞调用,所有的异步操作完成后,run()才返回。

    下面程序空有 io_context 对象,却没有任何异步操作,所以run()直接就返回了。

int main()
{  
    asio::io_context ioc;
    ioc.run();
    return 0;
}

2. asio::steady_timer

    asio::steady_timer可以实现同步调用机制。

    初始化时,第一个参数是asio::io_context,第二个参数设置定时器现在开始3秒后终止。

    wait()是一个阻塞等待,3秒后定时器终止时返回。接着打印“Hello, world!”。

int main()
{  
    asio::io_context ioc;
    asio::steady_timer timer(ioc, std::chrono::seconds(3));
    timer.wait();
    std::cout << "Hello, world!" << std::endl;
    return 0;
}

   asio::steady_timer也可以用来实现异步调用机制。

   async_wait()  执行异步等待,设置回调函数Print,当异步操作结束后(此处即定时器结束后)该函数会被调用。

   Asio保证回调句柄仅仅能被run()启动的当前线程所调用。如果run() 函数不执行,用于异步等待完成时的回调函数(此处即Print())将永远不会被调用。

void Print(std::error_code ec) {
    std::cout << "Hello, world!" << std::endl;
}

int main()
{  
    asio::io_context ioc;
    asio::steady_timer timer(ioc, std::chrono::seconds(3));
    timer.async_wait(&Print);   
    ioc.run();
    return 0;
}

    下例中每隔1秒打印一次计数,从0到2。

    async_wait回调函数的签名为 void (std::error_code),传递额外的参数时需要使用bind。

    Print函数中,计数小于3时,expires_at()推迟定时器的终止时间。async_wait()启动一个新的异步等待。计数大于3时,run()函数返回。

void Print(std::error_code ec, asio::steady_timer* timer, int *count) 
{
    if (*count < 3)
    {
        std::cout << *count << std::endl;
        ++(*count);       
        timer->expires_at(timer->expires_at() + std::chrono::seconds(1));
        timer->async_wait(std::bind(&Print, std::placeholders::_1, timer, count));
    }
}
int main(int argc, char** argv)
{  
    asio::io_context ioc;
    asio::steady_timer timer(ioc, std::chrono::seconds(3));
    int count = 0;
    timer.async_wait(std::bind(&Print,std::placeholders::_1, &timer, &count));
    ioc.run();
    return 0;
}

    

 类似资料: