boost.asio框架系列之定时器Timer

同步Timer

asio中提供的timer名为deadline_timer,它提供了超时计时的功能。首先以一个最简单的同步Timer为例来演示如何使用它。

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

    int main()
    {
        boost::asio::io_service io;
        boost::asio::deadline_timer timer(io, boost::posix_time::seconds(3));

        timer.wait();
        std::cout << "Hello, world!\n";

        return 0;
    }

首先常见了一个io_service对象,它提供了IO调度功能,asio库中的所有io操作都是基于它来执行的。然后创建了一个deadline_timer对象,它有两个参数,一个是io_service对象,另一个是超时时间。

创建了timer后,就可以调用wait函数来阻塞等待至timer超时了,它还有一种可以指定错误码的入参的重载形式,关于错误码后面再介绍。

异步Timer

同步timer虽然简单,但由于其会阻塞,在实际的项目中并不常用,而往往使用的是异步timer:指定一个回调函数,计时器超时后执行回调函数。asio中实现异步timer比较简单,示例如下:

    void print(const boost::system::error_code& /*e*/)
    {
        std::cout << "Hello, world!\n";
    }
    int main()
    {
        boost::asio::io_service io;
        boost::asio::deadline_timer timer(io, boost::posix_time::seconds(5));

        timer.async_wait(&print);
        io.run();

        return 0;
    }

和同步方式相比,它主要有两点不同:

  • 调用的是非阻塞函数async_wait,它的入参是一个回调函数。
  • 显式调用io_service.run()函数驱动异步IO调度。

取消Timer

Timer还有一种常用操作是取消Timer,基本方法如下:

  • 调用timer的cancel函数取消timer
  • timer取消后,回调函数会立即执行,通过err_code可以感知到计时器是否已经被取消
    void print(const boost::system::error_code& err)
    {
        if(err)
        {
            std::cout << "timer is canceled\n";
            return;
        }

        std::cout << "Hello, world!\n";
    }

    int main()
    {
        boost::asio::io_service io;

        boost::asio::deadline_timer timer(io, boost::posix_time::seconds(5));
        timer.async_wait(&print);

        boost::asio::deadline_timer timer2(io, boost::posix_time::seconds(2));
        timer2.wait();
        timer.cancel();

        io.run();
        return 0;
    }

更改Timer超时时间

可以通过expires_from_now和expires_at两个函数更改Timer的超时时间,如下示例就通过它实现一个周期计时器。

    typedef std::function<void (const boost::system::error_code&)> timer_callback ;
    void print(const boost::system::error_code&)
    {
        std::cout << "Hello, world!\n";
    }

    int main()
    {
        boost::asio::io_service io;
        boost::asio::deadline_timer timer(io, boost::posix_time::seconds(1));

        timer_callback callback = [&](const boost::system::error_code& err)
        {
            print(err);
            timer.expires_at(timer.expires_at() + boost::posix_time::seconds(1));
            timer.async_wait(callback);
        };

        timer.async_wait(callback);
        io.run();
        return 0;
    }

到此这篇关于boost.asio框架系列之定时器Timer的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C++ boost::asio编程-异步TCP详解及实例代码

    C++ boost::asio编程-异步TCP 大家好,我是异步方式 和同步方式不同,我从来不花时间去等那些龟速的IO操作,我只是向系统说一声要做什么,然后就可以做其它事去了.如果系统完成了操作, 系统就会通过我之前给它的回调对象来通知我. 在ASIO库中,异步方式的函数或方法名称前面都有"async_ " 前缀,函数参数里会要求放一个回调函数(或仿函数).异步操作执行 后不管有没有完成都会立即返回,这时可以做一些其它事,直到回调函数(或仿函数)被调用,说明异步操作已经完成. 在ASI

  • 快速了解Boost.Asio 的多线程模型

    Boost.Asio 有两种支持多线程的方式,第一种方式比较简单:在多线程的场景下,每个线程都持有一个io_service,并且每个线程都调用各自的io_service的run()方法. 另一种支持多线程的方式:全局只分配一个io_service,并且让这个io_service在多个线程之间共享,每个线程都调用全局的io_service的run()方法. 每个线程一个 I/O Service 让我们先分析第一种方案:在多线程的场景下,每个线程都持有一个io_service (通常的做法是,让线程

  • C++ boost::asio编程-域名解析详细介绍

    C++ boost::asio编程-域名解析 在网络通信中通常我们并不直接使用IP地址,而是使用域名.这时候我们就需要用reslover类来通过域名获取IP,它可以实现 与IP版本无关的网址解析. #include "stdafx.h" #include "boost/asio.hpp" #include "boost/shared_ptr.hpp" #include "boost/thread.hpp" #include &

  • C++ boost::asio编程-同步TCP详解及实例代码

    boost::asio编程-同步TCP boost.asio库是一个跨平台的网络及底层IO的C++编程库,它使用现代C++手法实现了统一的异步调用模型. boost.asio库支持TCP.UDP.ICMP通信协议. 下面介绍同步TCP模式: 大家好!我是同步方式! 我的主要特点就是执着!所有的操作都要完成或出错才会返回,不过偶的执着被大家称之为阻塞,实在是郁闷~~(场下一片嘘声),其实这样 也是有好处的,比如逻辑清晰,编程比较容易. 在服务器端,我会做个socket交给acceptor对象,让它

  • boost.asio框架系列之定时器Timer

    同步Timer asio中提供的timer名为deadline_timer,它提供了超时计时的功能.首先以一个最简单的同步Timer为例来演示如何使用它. #include <iostream> #include <boost/asio.hpp> int main() { boost::asio::io_service io; boost::asio::deadline_timer timer(io, boost::posix_time::seconds(3)); timer.wa

  • boost.asio框架系列之调度器io_service

    IO模型 io_service对象是asio框架中的调度器,所有异步io事件都是通过它来分发处理的(io对象的构造函数中都需要传入一个io_service对象). asio::io_service io_service; asio::ip::tcp::socket socket(io_service); 在asio框架中,同步的io主要流程如下: 应用程序调用IO对象成员函数执行IO操作 IO对象向io_service 提出请求. io_service 调用操作系统的功能执行连接操作. 操作系统

  • boost.asio框架系列之buffer函数

    创建buffer 在io操作中,对数据的读写大都是在一个缓冲区上进行的,在asio框架中,可以通过asio::buffer函数创建一个缓冲区来提供数据的读写.buffer函数本身并不申请内存,只是提供了一个对现有内存的封装. char d1[128]; size_t bytes_transferred = sock.receive(asio::buffer(d1)); 直接用字符串做buffer也是常见的形式: string str = " hello world " ; size_t

  • boost.asio框架系列之socket编程

    asio的主要用途还是用于socket编程,本文就以一个tcp的daytimer服务为例简单的演示一下如何实现同步和异步的tcp socket编程. 客户端 客户端的代码如下: #include <iostream> #include <boost/array.hpp> #include <boost/asio.hpp> using boost::asio::ip::tcp; int main(int argc, char* argv[]) { try { boost:

  • PHP框架Swoole定时器Timer特性分析

    本文所述PHP框架Swoole定时器Timer特性分析具有很好的实用价值,值得PHP程序开发人员学习借鉴.具体分析如下: 首先,在各种业务型系统中,往往需要服务器在后台扫描相关数据,触发相应的统计.通知等操作. 比如对于一个项目管理系统,需要每天的特定时间内,统计每项任务的执行.到期情况.整个项目的进度等等,根据统计情况,做相应通知处理: 这样一个场景,如何编程实现? 用一般的编程方式,是无法实现自动触发与统计的.当然,简单的思路,是利于系统的cron job机制.但这种方式,对于配置及可靠性方

  • Java中定时器Timer致命缺点案例详解

    目录 简介 案例1:定时器打印Hello World! 线程不死问题? 案例2:单线程问题 定时器实际应用场景 学习方法心得 总结 简介 这篇文章我一直在纠结到底要不要写,不想写一来因为定时器用法比较简单,二来是面试中也不常问.后来还是决定写了主要是想把自己分析问题思路分享给大家,让大家在学习过程中能够参考,学习态度我相信大部分人没有问题,特别是正在看我博文的小伙伴那更不用说了!!给你们点个狂力赞.接下来就是学习方法了,我发现近期来咨询我问题的小伙伴学习姿势不对,所以我用Java中定时器Time

  • Linux下实现定时器Timer的几种方法总结

    定时器Timer应用场景非常广泛,在Linux下,有以下几种方法: 1,使用sleep()和usleep() 其中sleep精度是1秒,usleep精度是1微妙,具体代码就不写了.使用这种方法缺点比较明显,在Linux系统中,sleep类函数不能保证精度,尤其在系统负载比较大时,sleep一般都会有超时现象. 2,使用信号量SIGALRM + alarm() 这种方式的精度能达到1秒,其中利用了*nix系统的信号量机制,首先注册信号量SIGALRM处理函数,调用alarm(),设置定时长度,代码

  • python通过线程实现定时器timer的方法

    本文实例讲述了python通过线程实现定时器timer的方法.分享给大家供大家参考.具体分析如下: 这个python类实现了一个定时器效果,调用非常简单,可以让系统定时执行指定的函数 下面介绍以threading模块来实现定时器的方法. 使用前先做一个简单试验: import threading def sayhello(): print "hello world" global t #Notice: use global variable! t = threading.Timer(5

随机推荐