boost asio 性能可以做什么

当前位置: →
→ Boost::asio ioservice 实现分析
Boost::asio ioservice 实现分析
& 作者及来源: 知然 - 博客园 &
&收藏到→_→:
摘要: Boost::asio io_service 实现分析
"Boost::asio ioservice 实现分析"::
boost::asio
io_service 实现分析
io_service的作用
io_servie 实现了一个任务队列,这里的任务就是void(void)的函数。io_servie最常用的两个接口是post和run,post向任务队列中投递任务,run是执行队列中的任务,直到全部执行完毕,并且run可以被n个线程调用。io_service是完全线程安全的队列。
io_servie的接口
提供的接口有run、run_one、poll、poll_one、stop、reset、dispatch、post,最常用的是run、post、stop
io_servie 实现代码的基本类结构:
lio_servie是接口类,为实现跨平台,采用了策略模式,所有接口均有impl_type实现。根据平台不同impl_type分为
nwin_iocp_io_service win版本的实现,这里主要分析linux版本。
ntask_io_service 非win平台下的实现,其代码结构为:
udetail/task_io_service_fwd.hpp 简单声明task_io_service名称
udetail/task_io_service.hpp 声明task_io_service的方法和属性
udetail/impl/task_io_service.ipp 具体实现文件
u队列中的任务类型为opertioan,原型其实是typedef
task_io_service_operation operation,其实现文件在detail/task_io_service_operation.hpp中,当队列中的任务被执行时,就是task_io_service_operation:: complete被调用的时候。
io_servie::post方法的实现
post向队列中投递任务,然后激活空闲线程执行任务。其实现流程如下:
lpost接收handler作为参数,实际上是个,通过此仿此文来自: 马开东博客
转载请注明出处 网址:
函数构造出completion_handler对象,completion_handler继承自operation。然后调用post_immediate_completion。
lpost_immediate_completion首先将outstanding_work_增加,然后调用post_deferred_completion。
lpost_deferred_completion首先加锁将任务入列,然后调用wake_one_thread_and_unlock
lwake_one_thread_and_unlock尝试唤醒当前空闲的线程,其实现中特别之处在于,若没有空闲线程,但是有线程在执行task-&run,即阻塞在epoll_wait上,那么先中断epoll_wait执行任务队列完成后再执行epoll_wait。
lfirst_idle_thread_维护了所有当前空闲线程,实际上使用了leader/follower模式,每次唤醒时只唤醒空闲线程的第一个。
io_servie::run方法的实现
&&&&&&&& run方法执行队列中的所有任务,直到任务执行完毕。
lrun方法首先构造一个idle_thread_info,和first_idle_thread_类型相同,即通过first_idle_thread_将所有线程串联起来,它这个串联不是立即串联的,当该线程无任务可做是加入到first_idle_thread_的首部,有任务执行时,从first_idle_thread_中断开。这很正常,因为first_idle_thread_维护的是当前空闲线程。
l加锁,循环执行do_one方法,直到do_one返回false
ldo_one每次执行一个任务。首先检查队列是否为空,若空将此线程追加到first_idle_thread_的首部,然后阻塞在条件变量上,直到被唤醒。
l当被唤醒或是首次执行,若stopped_为true(即此时stop方法被调用了),返回0
l队列非空,pop出一个任务,检查队列无任务那么简单的解锁,若仍有,调用wake_one_thread_and_unlock尝试唤醒其他空闲线程执行。然后执行该任务,返回1.
l实际上在执行队列任务时有一个特此文来自: 马开东博客
转载请注明出处 网址:
别的判断if (o == &task_operation_),那么将会执行task_-&run,task_变量类型为reactor,在linux平台实现为epoll_reactor,实现代码文件为detail/impl/epoll_reactor.ipp,run方法实际上执行的是epoll_wait,run阻塞在epoll_wait上等待事件到来,并且处理完事件后将需要回调的函数push到io_servie的任务队列中,虽然epoll_wait是阻塞的,但是它提供了interrupt函数,该interrupt是如何实现的呢,它向epoll_wait添加一个文件描述符,该文件描述符中有8个字节可读,这个文件描述符是专用于中断epoll_wait的,他被封装到select_interrupter中,select_interrupter实际上实现是eventfd_select_interrupter,在构造的时候通过pipe系统调用创建两个文件描述符,然后预先通过write_fd写8个字节,这8个字节一直保留。在添加到epoll_wait中采用epollet水平触发,这样,只要select_interrupter的读文件描述符添加到epoll_wait中,立即中断epoll_wait。很是巧妙。!!!实际上就是因为有了这个reactor,它才叫io_servie,否则就是一个纯的任务队列了。
lrun方法的原则是:
n有任务立即执行任务,尽量使所有的线程一起执行任务
n若没有任务,阻塞在epoll_wait上等待io事件
n若有新任务到来,并且没有空闲线程,那么先中断epoll_wait,先执行任务
n若队列中有任务,并且也需要epoll_wait监听事件,那么非阻塞调用epoll_wait(timeout字段设置为0),待任务执行完毕在阻塞在epoll_wait上。
n几乎对线程的使用上达到了极致。
n从这个函数中可以知道,在使用asio时,io_servie应该尽量多,这样可以使其epoll_wait占用的时间片最多,这样可以最大限度的响应io事件,降低响应时延。但是每个io_servie::run占用一个线程,所以io_servie最佳应该和cpu的核数相同。
io_servie::stop的实现
l加锁,调用stop_all_threads
l设置stopped_变量为true,遍历所有的空闲线程,依次唤醒
ltask_interrupted_设置为true,调用task_的interrupt方法
ltask_的类型为reactor,在run方法中已经做了分析
博客园_总排行榜
博客园_最新
博客园_月排行榜
博客园_周排行榜
博客园_日排行榜Posts - 82,
Articles - 0,
Comments - 12
好记性不如烂笔头
15:36 by jiayayao, ... 阅读,
  asio库基于操作系统提供的异步机制,采用前摄器模式(Proactor)实现可移植的异步(或同步)IO操作,不需要使用多线程和锁,有效避免多线程编程带来的诸多有害副作用(如竞争,死锁)。
  asio封装了操作系统的select、kqueue、poll/epoll、overlapped I/O等机制,实现异步IO模型。在同步模式下,程序发起一个IO操作,向io_service提交请求,io_service把操作转交给操作系统,同步地等待。当IO操作完成时,操作系统通知io_service,然后io_service再把结果发回给程序,完成整个同步流程。在异步模式下,程序除了要发起IO操作,还要定义一个用于回调的完成处理函数。io_service同样把IO操作转交给操作系统执行,但它不同步等待,而是立即返回。调用io_service的run()成员函数可以等待异步操作完成,当异步操作完成时io_service从操作系统获取结果,在调用handler执行后续逻辑。
1. handler
  回调函数形式:
void handler(const error_code &ec);
void handler(const error_code &ec, std::size_type bytes_transferred);
2. io_service
  io_service类代表了系统里的异步处理机制(如epoll),必须在asio库里的其他对象之前初始化,其他对象则向io_service提交异步操作handler。
3. const_buffer
  数据缓冲区,保存了一个void*的内存地址和数据长度。
4. 网络通信相关
  asio支持TCP、UDP和ICMP通信协议,很好的封装了伯克利socket api。其中TCP部分定义了一些用于TCP通信的typedef类型,包括端点类endpoint、套接字类socket、流类iostream,以及接收器acceptor、解析器resolver等。 
/// The type of a TCP endpoint.
typedef basic_endpoint&tcp&
/// The TCP socket type.
typedef basic_stream_socket&tcp&
/// The TCP acceptor type.
typedef basic_socket_acceptor&tcp&
/// The TCP resolver type.
typedef basic_resolver&tcp&
/// The TCP iostream type.
typedef basic_socket_iostream&tcp&
/// ......
  endpoint包含IP地址和通信用的端口号。
  socket可以在构造时指定使用的协议或者endpoint,或者稍后调用成员函数connect()。连接成功后可以用local_endpoint()和remote_endpoint()获得连接两端的端点信息,用available()获取可读取的字节数,用receive()/read_some()和send()/write_some()读写数据,当操作完成后使用close()函数关闭socket。如果socket没有被关闭,则其析构时也会自动关闭。
  acceptor对应Socket API的accept()函数,用于服务器端。acceptor可以像传统socket API一样使用,open()打开端口,bind()绑定再用listen()侦听端口,但更方便的是使用它的构造函数,传入endpoint直接完成这三个动作。
  实现例子:和。用户名:瓯裔
访问量:519
注册日期:
阅读量:1297
阅读量:3317
阅读量:583685
阅读量:468835
51CTO推荐博文
引言寸光阴,当下我们或许更需要利用现有的知识,应用现有的技术。网络是当前互联网的根本,了解网络便开始显得极其重要。今天我们利用Boost库中Asio部分,浅尝网络服务器。此处不做过于深入的开展,为达成学习目的,只做简单的异步并发服务器。注意:本篇代码没有直接引用boost等命名空间,为的是新入门Boost的同学能够更好的了解每个参数在boost的具体命名空间位置,有助于更好的理解boost的布局。版权所有:_OE_,转载请注明出处:码云源代码下载:CSDN代码下载:服务器用例我们在做服务器之前,首先细想一下,服务器应具备哪些基本特质。1、构建:一个服务器应该具备被连接的IP地址(网络地址)、可以被访问的Port(端口号)2、聆听:服务器应该能够实时处理基本的连接请求3、处理:交互才是目的,可以与客户端实现基本的交互4、异步:处理客户端的请求时,不会因为客户端的延迟响应而导致程序假死建造(Build)电脑里有非常多的端口,而客户端只会把消息传到约定的地址与端口,只有在正确的端口等待,才能接到自己预期的客户。就好像楼房里有非常多层楼一样,而快递员只会把物品送到约定的楼层,只有在正确的楼层等待,才能达成预期的结果。#include&&iostream&
#include&&boost/asio.hpp&
int&main(void)&{
std::cout&&&&"server&start."&&&&std::
//&asio程序必须的io_service对象
boost::asio::io_service&
//&具体的服务器地址与端口
boost::asio::ip::tcp::endpoint&endpotion(boost::asio::ip::tcp::v4(),&13695);
//&创建acceptor对象,当前的IPV4作为服务器地址(127.0.0.1&||&0.0.0.0),接受端口13695的消息.
boost::asio::ip::tcp::acceptor&acceptor(ios,&endpotion);
//&打印当前服务器地址
std::cout&&&&"addr:&"&&&&acceptor.local_endpoint().address()&&&&std::
//&打印当前服务器端口
std::cout&&&&"port:&"&&&&acceptor.local_endpoint().port()&&&&std::
catch&(...)&{
std::cout&&&&"server&exceptional."&&&&std::
std::cout&&&&"server&end."&&&&std::
getchar();
}聆听(Listen)一个基本的连接,在正常的情况下,应该由客户端发起,服务器应该处于实时监听的状态,因为能接到客户端发起的连接请求,这才是网络操作的根本。#include&&iostream&
#include&&boost/asio.hpp&
int&main(void)&{
std::cout&&&&"server&start."&&&&std::
//&asio程序必须的io_service对象
boost::asio::io_service&
//&具体的服务器地址与端口
boost::asio::ip::tcp::endpoint&endpotion(boost::asio::ip::tcp::v4(),&13695);
//&创建acceptor对象,当前的IPV4作为服务器地址(127.0.0.1&||&0.0.0.0),接受端口13695的消息.
boost::asio::ip::tcp::acceptor&acceptor(ios,&endpotion);
//&打印当前服务器地址
std::cout&&&&"addr:&"&&&&acceptor.local_endpoint().address()&&&&std::
//&打印当前服务器端口
std::cout&&&&"port:&"&&&&acceptor.local_endpoint().port()&&&&std::
//&循环执行服务
while&(true)&{
//&一个临时的socket对象
boost::asio::ip::tcp::socket&socket(ios);
//&阻塞等待客户端连接,连接成功后返回socket,&accept这个函数使用引用来调取socket.
acceptor.accept(socket);
//&打印与本机服务器取得连接的客户端IP地址
std::cout&&&&"client:&"&&&&socket.remote_endpoint().address()&&&&std::
catch&(std::exception&&_e)&{
std::cout&&&&"server&exceptional."&&&&std::
std::cout&&&&_e.what()&&&&std::
std::cout&&&&"server&end."&&&&std::
getchar();
}处理(Operation)一旦服务器收到客户端发起的连接请求,便为客户端建立服务。与客户端建立连接的目的,始终是为了交互,我们不能本末倒置。我们尝试一下,第一次交互的滋味。#include&&iostream&
#include&&boost/asio.hpp&
int&main(void)&{
std::cout&&&&"server&start."&&&&std::
//&asio程序必须的io_service对象
boost::asio::io_service&
//&具体的服务器地址与端口
boost::asio::ip::tcp::endpoint&endpotion(boost::asio::ip::tcp::v4(),&13695);
//&创建acceptor对象,当前的IPV4作为服务器地址(127.0.0.1&||&0.0.0.0),接受端口13695的消息.
boost::asio::ip::tcp::acceptor&acceptor(ios,&endpotion);
//&打印当前服务器地址
std::cout&&&&"addr:&"&&&&acceptor.local_endpoint().address()&&&&std::
//&打印当前服务器端口
std::cout&&&&"port:&"&&&&acceptor.local_endpoint().port()&&&&std::
//&循环执行服务
while&(true)&{
//&一个临时的socket对象
boost::asio::ip::tcp::socket&socket(ios);
//&阻塞等待客户端连接,连接成功后返回socket,&accept这个函数使用引用来调取socket.
acceptor.accept(socket);
//&打印与本机服务器取得连接的客户端IP地址
std::cout&&&&"client:&"&&&&socket.remote_endpoint().address()&&&&std::
//////////////////////////////处理/////////////////////////////////
std::string&
//&阻塞发送作者名称到客户端
socket.write_some(boost::asio::buffer("hello&CSND_Ayo"));
//&阻塞接收客户端发来的数据
socket.read_some(boost::asio::buffer(msg));
//&打印客户端发来的数据
std::cout&&&&"client&reply:&"&&&&msg.c_str()&&&&std::
catch&(std::exception&&_e)&{
std::cout&&&&"server&exceptional."&&&&std::
std::cout&&&&_e.what()&&&&std::
std::cout&&&&"server&end."&&&&std::
getchar();
}异步(Async)处理客户端的请求时,不会因为客户端的延迟响应而导致程序假死#include&&iostream&
#include&&boost/asio.hpp&
#include&&boost/bind.hpp&
//&异步服务器类
class&Server&{
//&服务实例
boost::asio::io_service&&ios_;
//&接收器实例
boost::asio::ip::tcp::acceptor&acceptor_;
//&socket智能指针
typedef&boost::shared_ptr&boost::asio::ip::tcp::socket&&socket_
Server(boost::asio::io_service&&_ios)&:&ios_(_ios),
acceptor_(_ios,&boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),&13695))&{
//&默认执行
//&启动网络侦听的操作入口
void&start(void)&{
//&自定义的智能指针
socket_ptr&socket(new&boost::asio::ip::tcp::socket(ios_));
//&异步侦听,若有服务连接,则自动调用Server::handler_accept函数,并将error,&socket传入作为参数
acceptor_.async_accept(*socket,
boost::bind(&Server::accept_handler,&this,
boost::asio::placeholders::error/*&此处作为占位符&*/,&socket));
//&请求者响应后触发的处理器
void&accept_handler(const&boost::system::error_code&&_ec,&socket_ptr&_socket)&{
//&错误码检测
if&(_ec)&{
//&打印当前连接进来的客户端
std::cout&&&&"client:&"&&&&_socket-&remote_endpoint().address()&&&&std::
//&异步发送&"hello&CSND_Ayo"&消息到客户端,发送成功后,自动调用Server::write_handler函数
_socket-&async_write_some(boost::asio::buffer("hello&CSND_Ayo"),
boost::bind(&Server::write_handler,&this,
boost::asio::placeholders::error/*&此处作为占位符&*/));
//&启动新的异步监听
//&完成异步写操作后的处理器
void&write_handler(const&boost::system::error_code&&_ec)&{
std::cout&&&&"server:&send&message&complete."&&&&std::
int&main(void)&{
std::cout&&&&"server&start."&&&&std::
//&建造服务对象
boost::asio::io_service&
//&构建Server实例
Server&server(ios);
//&启动异步调用事件处理循环
ios.run();
catch&(std::exception&&_e)&{
std::cout&&&&_e.what()&&&&std::
std::cout&&&&"server&end."&&&&std::
}作者的简易并发服务器类使用两个类来撰写了一个并发的服务器类Server(服务器监听类)、Session(会话类)具备功能:1、异步监听客户端连接2、客户连接时,首包要求具有特定格式(协议包)3、并发处理客户端交互650) this.width=650;" src="http://img.blog.csdn.net/13374?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ1NORF9BeW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />当前类的网络交互协议拓扑图Server.h#ifndef&__CLY_SERVER_H__
#define&__CLY_SERVER_H__
#include&&string.h&&&
#include&&boost/asio.hpp&
#include&&boost/shared_ptr.hpp&
class&Server&{
//&会话&-&智能指针
typedef boost::shared_ptr&Session& session_
Server(boost::asio::io_service&&_ioService,&boost::asio::ip::tcp::endpoint&&_endpoint);
virtual&~Server(void);
void&start(void);
void&run(void);
//&数据导出接口
void&callback_session(std::string&_fromIp,&std::string&_info);
//&会话启动
void&accept_handler(session_ptr&_chatSession,&const&boost::system::error_code&&_error);
boost::asio::io_service&&ioService_;
boost::asio::ip::tcp::acceptor&acceptor_;
#endif&//&__CLY_SERVER_H__Server.cpp#include&&boost/bind.hpp&
#include&"Server.h"
#include&"Session.h"
Server::Server(boost::asio::io_service&&_ioService,&boost::asio::ip::tcp::endpoint&&_endpoint)
:&ioService_(_ioService),&acceptor_(_ioService,&_endpoint)&{
Server::~Server(void)&{
void&Server::start(void)&{
session_ptr new_chat_session(new&Session(ioService_));
acceptor_.async_accept(new_chat_session-&socket(),
boost::bind(&Server::accept_handler,&this,&new_chat_session,
boost::asio::placeholders::error));
void&Server::run(void)&{
ioService_.run();
void&Server::callback_session(std::string&/*_fromIp*/,&std::string&/*_info*/)&{
void&Server::accept_handler(session_ptr&_chatSession,&const&boost::system::error_code&&_error)&{
if&(!_error&&&&_chatSession)&{
_chatSession-&start();
catch&(...)&{
}Session.h#ifndef&__CLY_SESSION_H__
#define&__CLY_SESSION_H__
#include&&iostream&
#include&&string&
#include&&boost/asio.hpp&
#include&&boost/enable_shared_from_this.hpp&
#define&REPLY_SIZE&(32)
class&Session&:&public&boost::enable_shared_from_this&Session&
typedef&void&pSessionCallback(std::string,&std::string);
Session(boost::asio::io_service&&_ioService);
virtual&~Session(void);
void&start(void);
void&setCallback(pSessionCallback*&_callback)&{&callback_&=&_&}
//&socket&实例
boost::asio::ip::tcp::socket&&socket(void);
//&第一个协议包
void&init_handler(const&boost::system::error_code&&_error);
//&解析协议包
void&analyse_handler(const&boost::system::error_code&&_error);
//&完成数据传输后触发的收尾工作
void&done_handler(const&boost::system::error_code&&_error);
//&读取成功后触发的函数
void&read_handler(const&boost::system::error_code&&_error,&size_t&_readSize);
//&写入完成后触发的函数
void&write_handler(const&boost::system::error_code&&_error);
//&临时信息缓冲区
char&msg_[1024];
std::string&currentMsg_;
//&数据总数量
int&sumSize_;
//&单个数据包大小
unsigned&int&maxSize_;
//&socket句柄
boost::asio::ip::tcp::socket&socket_;
pSessionCallback*&callback_;
#endif&//&__CLY_SESSION_H__Session.cpp#include&&boost/bind.hpp&
#include&"Session.h"
Session::Session(boost::asio::io_service&&_ioService)
:socket_(_ioService)&{
memset(msg_,&0,&sizeof(msg_));
Session::~Session(void)
void&Session::start(void)&{
//&告诉链接成功的客户端,你想要的信息。
char&msg[256]&=&"001:Connect&Succeed!&Please&tell&me&with&10&bytes,&the&total&data&and&the&size&of&each&package,&example:128&1024";
boost::asio::async_write(socket_,&boost::asio::buffer(msg,&strlen(msg)),
boost::bind(&Session::init_handler,&shared_from_this(),
boost::asio::placeholders::error));
boost::asio::ip::tcp::socket&&Session::socket(void)&{
return&socket_;
//&第一个协议包
void&Session::init_handler(const&boost::system::error_code&&_error)&{
if&(_error)&{
//&读取客户端发来的&10&bytes,确定单个包的大小以及数据总大小
boost::asio::async_read(socket_,&boost::asio::buffer(msg_,&10),
boost::bind(&Session::analyse_handler,&shared_from_this(),
boost::asio::placeholders::error));
void&Session::analyse_handler(const&boost::system::error_code&&_error)&{
if&(_error)&{
//&分析协议包格式
bool&bflag&=&
//&正则分析格式
//&do&something.
if&(!bflag)&{
//&格式化保存协议包数据
std::stringstream&io(msg_);
io&&&&maxSize_;
io&&&&sumSize_;
//&发送接收请求信息
char&msg[REPLY_SIZE];
sprintf_s(msg,&"001:is&ok,&data&remaining&%d.",&sumSize_);
boost::asio::async_write(socket_,&boost::asio::buffer(msg,&REPLY_SIZE),
boost::bind(&Session::write_handler,&shared_from_this(),
boost::asio::placeholders::error));
//&完成数据传输
void&Session::done_handler(const&boost::system::error_code&&_error)&{
if&(_error)&{
currentMsg_&+=&msg_;
//&发送信息到回调
if&(!currentMsg_.empty()&&&&callback_&!=&nullptr)&{
callback_(socket_.remote_endpoint().address().to_string(),&currentMsg_);
currentMsg_.clear();
memset(msg_,&0,&sizeof(msg_));
char&msg[32]&=&"001:will&done.";
boost::asio::async_write(socket_,&boost::asio::buffer(msg,&REPLY_SIZE),
boost::bind(&Session::init_handler,&shared_from_this(),
boost::asio::placeholders::error));
void&Session::read_handler(const&boost::system::error_code&&_error,&size_t&_readSize)&{
if&(_error)&{
//&数据处理
currentMsg_&+=&msg_;
if&(currentMsg_.size()&&&1024&*&512)&{
//&发送信息到回调
if&(callback_&!=&nullptr)&{
callback_(socket_.remote_endpoint().address().to_string(),&currentMsg_);
currentMsg_.clear();
memset(msg_,&0,&sizeof(msg_));
//&计算当前剩余数据数量
sumSize_&-=&_readS
//&接收完成
if&(0&&&sumSize_)&{
done_handler(_error);
//&继续接收
char&msg[REPLY_SIZE];
sprintf_s(msg,&"001:%d.",&sumSize_);
boost::asio::async_write(socket_,&boost::asio::buffer(msg,&REPLY_SIZE),
boost::bind(&Session::write_handler,&shared_from_this(),
boost::asio::placeholders::error));
std::cout&&&&"send&client&recv&succeed:&"&&&&msg&&&&std::
void&Session::write_handler(const&boost::system::error_code&&_error)&{
if&(_error)&{
boost::asio::async_read(socket_,&boost::asio::buffer(msg_,&maxSize_),
boost::bind(&Session::read_handler,&shared_from_this(),
boost::asio::placeholders::error,&boost::asio::placeholders::bytes_transferred));
}main.cpp#include&&iostream&
#include&&boost/asio.hpp&
#include&&boost/bind.hpp&
#include&"Server.h"
int&main(void)&{
std::cout&&&&"server&start."&&&&std::
//&建造服务对象
boost::asio::io_service&
//&具体的服务器地址与端口
boost::asio::ip::tcp::endpoint&endpotion(boost::asio::ip::tcp::v4(),&13695);
//&构建Server实例
Server&server(ios,&endpotion);
//&启动异步调用事件处理循环
server.run();
catch&(std::exception&&_e)&{
std::cout&&&&_e.what()&&&&std::
std::cout&&&&"server&end."&&&&std::
}本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:未分类┆阅读(0)┆评论(0)阅读(1101)
平台:win2k或者以上1、投递多个accept请求这个也是对应以前完成端口的投递若干个wsaaccept的
for(int index=0;index<32;index++)
HqSessionPtr new_connection(new HqSession(_io_service));
new_acceptor->async_accept(new_connection->socket(),
boost::bind(&HqSessionMgr::handle_accept, this,new_connection,new_acceptor,boost::asio::placeholders::error));
}2、同时监听多个端口 g_ui_log->info("服务器启动,ThreadSize(%d)",_thread_pool_size); for(std::set::iterator it=_listen_ports.begin();it!=_listen_ports.end();it++) {
int curport=*
using boost::asio::ip::
tcp::endpoint endpoint(tcp::v4(),curport);
//这里是根据每个监听端口创个新的acceptor
boost::asio::ip::tcp::acceptor *new_acceptor=new boost::asio::ip::tcp::acceptor(_io_service,endpoint);
_acceptors.push_back(new_acceptor);
g_ui_log->info("开始监听端口:%d",curport);
for(int index=0;index<32;index++)
//这里是写死了投递32个,也可以从配置文件读入。
HqSessionPtr new_connection(new HqSession(_io_service));
new_acceptor->async_accept(new_connection->socket(),
boost::bind(&HqSessionMgr::handle_accept, this,new_connection,new_acceptor,boost::asio::placeholders::error));
catch(...)
g_ui_log->info("监听端口失败:%d",curport);
} }这边是对每个端口进行投递3、每个session同时只有同一个线程里处理。这个具体用strand估计大家都知道了。这种做法有别于以前的用锁来实现,这样做了后就可以不用锁,而且处理线程不用等待。我只稍微说一下原理。原理是这样的,每次读,写请求其实都是一个类似函数指针的东东,strand就是维护着一个列表,每个读写请求来了后会看这个session是否有正在处理的请求,如果有的话就直接丢列表,每次处理的请求完毕后,会看列表里是否有请求,如果有的话,把这个直接重新post到io_service里去。用boost.asio的感觉还可以,上面只是我做为初学者的一些感觉,高手一笑而过吧。
您还没有登录,请或
访问:180806次
积分:1980分
排名:第5名
随笔:198篇
评论:522条
阅读排行榜
评论排行榜
cxxjava:java的api确实设计的非常易用,c++也能做到近似,欢迎访问:
https://github....
amber:windows 下怎么安装配置freetds?网上找了很久都只是针对Linux的
e:SDL_im-1.2.8-.diff.gz这个文件你还有吗?
test: 下载不了啊
baby:哪些更适合宝宝?
gaoqing000:re: 语言之争的本质是计算机科学专业细分的结果。
年轻的时候,多学一些好些,
比如就像你,你的...
gaoqing000:re: 语言之争的本质是计算机科学专业细分的结果。
听君一席话大家成专家
WhenSoWeWent:re: 语言之争的本质是计算机科学专业细分的结果。
听君一席话胜读十年书
周星星:re: vs2010的一个EWOULDBLOCK的郁闷事情。(所有想在vc2010下写网络程序的可能...
Diviner:re: vs2010的一个EWOULDBLOCK的郁闷事情。
具体可见:
http://msdn....

我要回帖

更多关于 boost asio 中文教程 的文章

 

随机推荐