• 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.

    同步定时器

    /**
     * @brief 测试定时器同步调用
     */
    #include 
    #include 
    #include 
    #include 
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    异步定时器

    /**
     * @brief 测试定时器异步调用
     */
    #include 
    #include 
    #include 
    
    #include 
    #include 
    #include 
    #include 
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    work和io_service关系

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

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

    boost::asio::io_service io;
    boost::asio::io_service::work work(io);
    io.run();
    
    • 1
    • 2
    • 3

    deadline_timer的用法参考:
    https://blog.csdn.net/Erice_s/article/details/129965005

  • 相关阅读:
    【图像分割】基于萤火虫优化的半监督谱聚类彩色图像分割方法(Matlab代码实现)
    webrtc媒体服务器介绍
    科技云报道:从百度智能云的探索,看懂边缘云的过去和未来
    3 编写Makefiles
    ZLMeidaKit在Windows上启动时:计算机中丢失MSVCR110.dll,以及rtmp推流后无法转换为flv视频流解决
    方形图片 圆形图片 各种形状
    Hyperledger Fabric无排序组织以Raft协议启动多个Orderer服务、TLS组织运行维护Orderer服务
    络达开发---自定义BLE服务(一):相关数据结构讲解
    setTimeout() 和 setIntervale() 小结
    智能合约介绍
  • 原文地址:https://blog.csdn.net/Erice_s/article/details/133688731