asio中的定时器steady_timer和deadline_timer

  1. steady_timer的expires_from_now函数参数必须使用std::chrono
  2. deadline_timer的expires_from_now函数参数必须使用boost::posix_time
  3. deadline_timer使用的计量时间是系统时间,它是存在 trap 的, 如果 deadline_timer 正在做 time wait, 在系统时间被外部修改的时候, 是会导致deadline_timer 产生不可预期的影响的, 因为deadline_timer 是受系统时间影响的. 如果需要使用一个稳定不受系统时间影响的定时器建议使用 steady_timer.

同步定时器

cpp 复制代码
/**
 * @brief 测试定时器同步调用
 */
#include <iostream>
#include <chrono>
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>

using namespace boost;

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

异步定时器

cpp 复制代码
/**
 * @brief 测试定时器异步调用
 */
#include <iostream>
#include <chrono>
#include <thread>

#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>

using namespace boost;

asio::io_service *g_io = nullptr;

void Print(const system::error_code &ec, asio::steady_timer *timer, int *count)
{
	if (ec)
		return;
	
	if (*count < 3)
	{
		std::cout << "Count: " << *count << std::endl;
		++(*count);
		timer->expires_from_now(std::chrono::milliseconds(1000));
		// timer->expires_at(timer->expires_at() + std::chrono::seconds(1)));
		timer->aysnc_wait(boost::bind(&Print, boost::asio::placeholders::error, timer, count));
	}
	else
	{
		g_io->stop();
	}
}

int DoProcess(asio::steady_timer *timer, int* count)
{
	sleep(1);
	timer->aysnc_wait(boost::bind(&Print, boost::asio::placeholders::error, timer, count));
	sleep(8);
	return 0;
}

int main(int argc, char * argv[])
{  
    int count = 0;
    asio::io_service io;
	asio::io_service::work work(io);
    asio::steady_timer timer(io, std::chrono::seconds(3));
	g_io = &io;
	
	// 这里使用指针传递 可以使用std::ref(count)传递引用
	std::thread t(DoProcess, &timer, &count);
	std::cout << "run before..." << std::endl;
    io.run();
	std::cout << "run after..." << std::endl;
    if (t.joinable())
		t.join();
	
    return 0;
}

work和io_service关系

由于io_service并不会主动创建调度线程,需要我们手动分配,常见的方式是给其分配一个线程,然后执行run函数。但run函数在io事件完成后会退出,线程会终止,后续基于该对象的异步io任务无法得到调度。

解决这个问题的方法是通过一个boost::asio::io_service::work对象来守护io_service。这样,即使所有io任务都执行完成,也不会退出,继续等待新的io任务。

cpp 复制代码
boost::asio::io_service io;
boost::asio::io_service::work work(io);
io.run();

deadline_timer的用法参考:

https://blog.csdn.net/Erice_s/article/details/129965005

相关推荐
鑫鑫向栄9 分钟前
[蓝桥杯]修改数组
数据结构·c++·算法·蓝桥杯·动态规划
鑫鑫向栄10 分钟前
[蓝桥杯]带分数
数据结构·c++·算法·职场和发展·蓝桥杯
m0_552200821 小时前
《UE5_C++多人TPS完整教程》学习笔记37 ——《P38 变量复制(Variable Replication)》
c++·游戏·ue5
小wanga1 小时前
【递归、搜索与回溯】专题三 穷举vs暴搜vs回溯vs剪枝
c++·算法·机器学习·剪枝
Code_流苏2 小时前
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
开发语言·c++·stl容器·课设·期末大作业·日历程序·面向对象设计
liulun3 小时前
Skia如何绘制几何图形
c++·windows
old_power3 小时前
UCRT 和 MSVC 的区别(Windows 平台上 C/C++ 开发相关)
c语言·c++·windows
獨枭3 小时前
彻底解决 MFC 自绘控件闪烁
c++·mfc
獨枭3 小时前
MFC Resource.h 文件详解与修改指南
c++·mfc
鑫鑫向栄3 小时前
[蓝桥杯]堆的计数
数据结构·c++·算法·蓝桥杯·动态规划