
加载中…
个人资料
- 博客访问:
- 关注人气:
- 获赠金笔: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
赠金笔
加载中,请稍候......