加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

使用boost::asio::strand在多线程程序中进行回调同步

(2013-03-05 09:23:32)
标签:

杂谈

// 使用boost::asio::strand在多线程程序中进行回调同步(synchronise).
// 在单线程程序中用boost::asio::io_service::run()进行同步.
// asio库确保 仅当当前线程调用boost::asio::io_service::run()时产生回调.
// 显然,仅在一个线程中调用 boost::asio::io_service::run() 来确保回调是适用于并发编程的.
// 但是单线程有如下的限制,这一点在服务器上尤其明显:
// 当回调耗时较长时,反应迟钝.
// 在多核的系统上无能为力
// 解决的办法是建立一个boost::asio::io_service::run()的线程池.
// 然而这样就允许回调函数并发执行.所以,当回调函数需要访问一个共享,线程不安全的资源时,我们需要一种方式来同步操作.

#include <stdio.h>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

class printer
{
public:
    //boost::asio::strand 可以分配的回调函数.
    //它保证无论有多少线程调用了boost::asio::io_service::run(),
    //下一个回调函数仅在前一个回调函数完成后开始,
    //当然回调函数仍然可以和那些不使用boost::asio::strand分配,
    //或是使用另一个boost::asio::strand分配的回调函数一起并发执行.
    printer(boost::asio::io_service& io)
        : strand_(io),
        timer1_(io, boost::posix_time::seconds(1)),
        timer2_(io, boost::posix_time::seconds(1)),
        count_(0)
    {
        //当一个异步操作开始时,用boost::asio::strand来 "wrapped(包装)"回调函数.
        //boost::asio::strand::wrap()会返回一个由boost::asio::strand分配的新的handler(句柄),
        //这样,我们可以确保它们不会同时运行.
        timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1, this)));
        timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2, this)));
    }
    ~printer()
    {
        printf("Final count is %d\n", count_ );
    }
    //两个回调函数共享 count_ 变量
    void print1()
    {
        if (count_ < 10)
        {
            printf("Timer 1: %d \n", count_++);
            timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(1));
            timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1, this)));
        }
    }
    void print2()
    {
        if (count_ < 10)
        {
            printf("Timer 2: %d \n", count_++);
            timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(1));
            timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2, this)));
        }
    }
private:
    boost::asio::strand strand_;
    boost::asio::deadline_timer timer1_;
    boost::asio::deadline_timer timer2_;
    int count_;
};

int main()
{
    //main函数中boost::asio::io_service::run()在两个线程中被调用:主线程、一个boost::thread线程.
    //正如单线程中那样,并发的boost::asio::io_service::run()会一直运行直到完成任务.
    //后台的线程将在所有异步线程完成后终结.
    boost::asio::io_service io;
    printer p(io);
    boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
    io.run();
    t.join();
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有