码迷,mamicode.com
首页 > 其他好文 > 详细

BOOST ASIO 学习专贴

时间:2017-06-11 12:03:02      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:return   and   ted   expires   演示   原因   join   oid   wait函数   

1.同步使用Timer


本便使用了boost::asio::deadline_timer,这个timer有两种状态:过期和不过期。wait函数调用一个过期的timer直接返回。

int _tmain(int argc, _TCHAR* argv[])
{
    boost::asio::io_service io;
    boost::asio::deadline_timer t(io,boost::posix_time::seconds(5));
    t.wait();
    std::cout<<"wait finished!"<<std::endl;
    return 0;
}

2.异步使用Timer

下在演示了使用deadline_timer的asyn_wati函数实现异步等待。但要注意的一点是异步等待必须要调用io.run才可以。而且必须在io.run函数执行之前调用asyn_wait,否则io.run会立即返回,因为他没有可以做的事。这说明io.run必须至少有一个等待的,否则它会直接返回。asio函数保证回调函数执行和io.run所在的线程一样!

//异步Timer
void print(const boost::system::error_code & )
{
    std::cout<<"Wait Finished"<<std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
    boost::asio::io_service io;
    boost::asio::deadline_timer t(io,boost::posix_time::seconds(5));
    t.async_wait(&print);
    io.run();

    return 0;
}

3.为回调函数绑定参数

这个例子一个是说明异步Timer的可持续性问题,也就是在回调中设置Time的超时时间。另一个说明回调函数参数的绑定 。但是实际发现我官的代码没有发生那个重复回调的效果。原因是我只是调用了expire_at而没有调用再次等待函数async_wait。这让我更加明白expires_at这个函数相当于下次触发的时间。而async_wait提交一个等待申请。

async_wait提交一次,回调函数执行一次,而expire_at设定下次回调函数调用的时间。

#include <boost/bind.hpp>
void Print(const boost::system::error_code & ,
           boost::asio::deadline_timer * t,int * count)
{
    if(*count < 5)
    {
        std::cout<<*count<<std::endl;
        ++(*count);
        t->expires_at(t->expires_at() + boost::posix_time::seconds(1));
        t->async_wait(boost::bind(Print,boost::asio::placeholders::error,t,count));
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    boost::asio::io_service io;
    int count = 0;
    boost::asio::deadline_timer t(io,boost::posix_time::seconds(1));
    t.async_wait(boost::bind(Print,boost::asio::placeholders::error,&t,&count));
    io.run();
    return 0;
}

4.类成员做为timer的回调函数

这个例子主要演示了,如何绑定一个类成员函数作为一个回调

class Print
{
public:
    Print(boost::asio::io_service & io)
        :timer_(io,boost::posix_time::seconds(1)),count_(0)
    {
        timer_.async_wait(boost::bind(&Print::print,this));
    }
    ~Print()
    {
        std::cout<<"finnal count is "<<count_<<std::endl;
    }
    void print()
    {
        if(count_ < 5)
        {
            std::cout<<count_<<std::endl;
            ++count_;
            timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1));
            timer_.async_wait(boost::bind(&Print::print,this));
        }
    }
protected:
    boost::asio::deadline_timer timer_;
    int count_;
};

int _tmain(int argc, _TCHAR* argv[])
{
    boost::asio::io_service io;
    Print p(io);
    io.run();
    return 0;
}

4.在多线程程序中的同步回调

先前的例子通过io_service.run和同步回调在同一个线程内,正如你所知的那样,asio保证回调函数只能被在io_service.run()所在的线程调用 。因此,只有在一个线程内调用io_service::run保证回调函数不会并发执行。这样在服务器程序中有两个局限性:

1.当回调函数执行时间比较长时响应太慢
2.没有起到多处理器的优势

如果你注意到这个局限性,一个可供选择的方案是创建一个线程池去调用io_service.run()函数,这样实现的回调的并发,我们需要去同步一个共享变量。

下面的例子使用到了An boost::asio::strand ,他保证这些回调函数通过strans派遣,它可以允许一个回调函数在另一个回调函数执行之前完成。

#include <boost/thread/thread.hpp>

class printer
{
public:
    printer(boost::asio::io_service & io)
        :strand_(io),
        timer1_(io,boost::posix_time::seconds(1)),
        timer2_(io,boost::posix_time::seconds(1)),
        count_(0)
    {
        timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1,this)));
        timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2,this)));
    }
    void print1()
    {
        if(count_ < 10)
        {
            std::cout<<"Timer 1:"<<count_<<std::endl;
            ++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)
        {
            std::cout<<"Timer 2:"<<count_<<std::endl;
            ++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::io_service::strand strand_;
    boost::asio::deadline_timer timer1_;
    boost::asio::deadline_timer timer2_;
    int count_;
};
int _tmain(int argc, _TCHAR* argv[])
{
    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;
}

下面有时间研究一下 boost::asio::strand的用法

BOOST ASIO 学习专贴

标签:return   and   ted   expires   演示   原因   join   oid   wait函数   

原文地址:http://www.cnblogs.com/zhangdongsheng/p/6984634.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!