Chinaunix首页 | 论坛 | 博客
  • 博客访问: 151843
  • 博文数量: 54
  • 博客积分: 1732
  • 博客等级: 上尉
  • 技术积分: 520
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-23 23:29
文章分类

全部博文(54)

文章存档

2011年(3)

2010年(26)

2009年(25)

分类: C/C++

2010-01-30 22:44:15

我们知道,在类unix系统中,可以使用setitimer函数来设置一个计时器,让系统周期性的发送SIGALRM信号给进程,通过sigaction函数注册SIGALRM信号的回调函数,就可以使我们的进程周期性的处理特定任务。

上面是典型的C的思考方式,在C++中,当然也可以完全按照上面的思路来完成任务,但是这样的做法有一个很大的局限性:sigaction函数不支持注册类的成员函数,我曾经尝试用std::mem_fun解决这个问题,可能是自己太菜,也可能是没用心去研究,反正就是可耻的失败鸟。这里介绍一个替代方案,将上述产生timer的过程与回调函数的注册封装到一起实现。

首先下载头文件。
里面封装了一个basic_repeating_timer模板类,并且对最常用的模板参数做了typedef处理
typedef basic_repeating_timer<boost::posix_time::ptime> repeating_timer;

该模板类接口基本上看名字就可以理解其作用:
  • repeating_timer( io_service ) -构造函数
  • void start( repeat_interval, handler ) - 启动计时器,设置重复时间以及相应的回调函数
  • void stop(), void cancel() -停止/取消计时器
  • void change_interval( repeat_interval ) - 更改重复时间
该模板类的作者写了一个例子,原文参见
我把里面的example函数改成main函数后,得到源文件如下:



#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/ptr_container/ptr_array.hpp>

#include "basic_repeating_timer.h"


// callback hander for out timers

void handle_timeout( int id, boost::system::error_code const& error )
{
    std::cout << "timer " << id << " fired\n";
}

int main()
{
    // example shows io_service running in multiple thread, with multiple timers

    boost::thread_group threads;
    boost::asio::io_service my_io_service;

    boost::ptr_array<boost::asio::repeating_timer,10> timers;

    // create timers

    for( size_t i = 0; i < timers.size(); ++i )
    {
        timers.replace( i, new boost::asio::repeating_timer(my_io_service) );
    }

    // start them with their callbacks referencing the next timer

    for( size_t i = 0; i < timers.size(); ++i )
    {
        timers[i].start( boost::posix_time::seconds(i+1),
                         boost::bind( &handle_timeout,
                                      i,
                                      boost::asio::placeholders::error ) );
    }

    std::cout << "Press enter to stop the timers...\n";

    // finally we start the service running. If the service has nothing to work

    // with it will exit immediately.

    for( size_t i = 0; i < 5; ++i )
    {
        threads.create_thread( boost::bind(&boost::asio::io_service::run, &my_io_service) );
    }

    // wait for the enter/return key to be pressed

    std::cin.get();

    // explicitly cancel the timers

    // could just call timers.release() which would destroy the timer objects but

    // for completeness I wanted to show the cancel.

    for( size_t i = 0; i < timers.size(); ++i )
    {
        timers[i].cancel();
    }

    // and then wait for all threads to complete

    threads.join_all();

    return 0;
}

将上述文件保存为main.cc,编译运行:
$ c++ -lboost_thread -lboost_system main.cc
$ ./a.out 
Press enter to stop the timers...
timer 0 fired
timer 0 fired
timer 1 fired
timer 2 fired

为了验证该repeating_timer类能将成员函数注册为回调函数,我对其进行了简单的修改:


                                                                                 

#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/ptr_container/ptr_array.hpp>

#include "basic_repeating_timer.h"

class handler{
public:
    void handle_timeout( int id, boost::system::error_code const& error );
};

// callback hander for out timers

void handler::handle_timeout( int id, boost::system::error_code const& error )
{
    std::cout << "timer " << id << " fired\n";
}

int main()
{
    // example shows io_service running in multiple thread, with multiple timers

    boost::thread_group threads;
    boost::asio::io_service my_io_service;

    boost::ptr_array<boost::asio::repeating_timer,10> timers;
    handler han;

    // create timers

    for( size_t i = 0; i < timers.size(); ++i )
    {
        timers.replace( i, new boost::asio::repeating_timer(my_io_service) );
    }

    // start them with their callbacks referencing the next timer

    for( size_t i = 0; i < timers.size(); ++i )
    {
        timers[i].start( boost::posix_time::seconds(i+1),
                         boost::bind( &handler::handle_timeout,
                                      han,
                                      i,
                                      boost::asio::placeholders::error ) );
    }

    std::cout << "Press enter to stop the timers...\n";

    // finally we start the service running. If the service has nothing to work

    // with it will exit immediately.

    for( size_t i = 0; i < 5; ++i )
    {
        threads.create_thread( boost::bind(&boost::asio::io_service::run, &my_io_service) );
    }

    // wait for the enter/return key to be pressed

    std::cin.get();

    // explicitly cancel the timers

    // could just call timers.release() which would destroy the timer objects but

    // for completeness I wanted to show the cancel.

    for( size_t i = 0; i < timers.size(); ++i )
    {
        timers[i].cancel();
    }

    // and then wait for all threads to complete

    threads.join_all();

    return 0;
}

改动主要有两处,一是定义了一个handler类,并将handle_timeout置为其成员函数,二是在调用timers.start()函数是,第二个参数做了相应的修改,这里的修改是参照boost中文文档做的,其实我对这个bind基本没什么理解,照猫画虎而已,修改后编译运行:
$ c++ -lboost_thread -lboost_system memFun.cc -o memfun
$ ./memfun
Press enter to stop the timers...
timer 0 fired
timer 0 fired
timer 1 fired
timer 2 fired

事实证明,我这个虎画的还挺像那么回事^_^


阅读(1929) | 评论(0) | 转发(0) |
0

上一篇:boost安装初体验

下一篇:eps格式日历编辑

给主人留下些什么吧!~~