boost oracle 连接池,为什么在使用Boost:ASIO时每个连接都需要串?

文件是正确的。具有半双工协议实现,如HTTP Server 3,strand没有必要。呼叫链可说明如下:void connection::start(){

socket.async_receive_from(..., &handle_read);  ----.}

.------------------------------------------------'

|      .-----------------------------------------.

V      V                                         |void connection::handle_read(...)

boost::asio::async_write(..., &handle_write); ---|--.

else if (!result)                                  |  |

boost::asio::async_write(..., &handle_write);  --|--|

else                                               |  |

socket_.async_read_some(..., &handle_read);  ----'  |}

.---------------------------------------------------'

|

Vvoid handle_write(...)

如图所示,每个路径只启动一个异步事件。不可能并发执行处理程序或操作。socket_,据说它是以一种隐含的方式运行的。

螺纹安全

虽然在这个示例中它本身并不是一个问题,但我想强调一个关于链和组合操作的重要细节,例如boost::asio::async_write..在解释细节之前,让我们先用Boost.Asio介绍线程安全模型。对于大多数Boost.Asio对象来说,对一个对象进行多个异步操作是安全的;只是指定对象的并发调用是不安全的。在下面的图表中,每一列代表一个线程,每一行表示一个线程在某个时刻所做的事情。

单个线程执行顺序调用是安全的,而其他线程则不执行:thread_1                             | thread_2

--------------------------------------+---------------------------------------

socket.async_receive(...);            | ...

socket.async_write_some(...);         | ...

多个线程进行调用是安全的,但不是并发的:thread_1                             | thread_2

--------------------------------------+---------------------------------------

socket.async_receive(...);            | ...

...                                   | socket.async_write_some(...);

但是,多线程并发调用是不安全的。1:thread_1                             | thread_2

--------------------------------------+---------------------------------------

socket.async_receive(...);            | socket.async_write_some(...);

...                                   | ...

为了防止并发调用,处理程序通常是从链内调用的。这是通过以下两种方法之一实现的:用..这将返回一个新的处理程序,它将通过链分派。

或直接穿过钢绞线。

组合操作是唯一的,因为对溪流在处理程序如果一个链存在,而不是开始合成操作的链。与其他操作相比,这是一个链指定位置的倒置。下面是一些集中于串使用的示例代码,它将演示通过非组合操作读取的套接字,并与组合操作并发写入该套接字。void start(){

// Start read and write chains.  If multiple threads have called run on

// the service, then they may be running concurrently.  To protect the

// socket, use the strand.

strand_.post(&read);

strand_.post(&write);}// read always needs to be posted through the strand because it invokes a

// non-composed operation on the socket.void read(){

// async_receive is initiated from within the strand.  The handler does

// not affect the strand in which async_receive is executed.

socket_.async_receive(read_buffer_, &handle_read);}// This is not running within a strand, as read did not wrap it.void handle_read(){

// Need to post read into the strand, otherwise the async_receive would

// not be safe.

strand_.post(&read);}// The entry into the write loop needs to be posted through a strand.

// All intermediate handlers and the next iteration of the asynchronous write

// loop will be running in a strand due to the handler being wrapped.void write(){

// async_write will make one or more calls to socket_.async_write_some.

// All intermediate handlers (calls after the first), are executed

// within the handler's context (strand_).

boost::asio::async_write(socket_, write_buffer_,

strand_.wrap(&handle_write));}// This will be invoked from within the strand, as it was a wrapped

// handler in write().void handle_write(){

// handler_write() is invoked within a strand, so write() does not

// have to dispatched through the strand.

write();}

Handler类型的重要性

此外,在组合操作中,Boost.Asio使用参数相关查找(ADL)通过完成处理程序的链调用中间处理程序。因此,重要的是完成处理程序的类型具有适当的asio_handler_invoke()钩子。如果类型擦除发生在没有适当类型的类型中。asio_handler_invoke()钩子,例如一个boost::function的返回类型构造strand.wrap,然后中间处理程序将在链外执行,并且只有完成处理程序将在链内执行。看见这,这个请回答更多细节。

在以下代码中,所有中间处理程序和完成处理程序将在链内执行:boost::asio::async_write(stream, buffer, strand.wrap(&handle_write));

在下面的代码中,只有完成处理程序将在字符串中执行。中间处理程序不会在链内执行:boost::function handler(strand.wrap(&handle_write));boost::asio::async_write(stream, buffer, handler);

1.修订史记录这个规则的异常。如果得到操作系统的支持,同步读、写、接受和连接操作都是线程安全的。我在这里包括它的完整性,但建议谨慎使用它。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值