繁体   English   中英

增强ASIO阻止回调

[英]Boost ASIO blocking callbacks

从asio到阻塞的回调是否安全(或合理)?

void Connection::start() {
    /* Assume std::string buffer; that has data to write. */
    auto callbackFn = boost::bind(&Connection::callback, shared_from_this(),
                                  boost::asio::placeholders::error,
                                  boost::asio::placeholders::bytes_transferred);

  boost::asio::async_write(_socket, boost::asio::buffer(buffer), callBackFn);
}

void Connection::callback(const boost::system::error_code& error,
                              std::size_t bytesSent) {
    /* Perform long running action with bytes sent */
    boost::asio::async_write(...);
}

还是应该在回调中生成线程,然后立即返回并在该线程完成后执行操作?

是的,在许多情况下都是合理的。 但是,作为架构师,您有责任确定在您的情况下这是否合理。

一般而言,您的io_service将在一个线程上运行,即它将在其上调用回调的线程,这意味着它在调用回调时未处理消息。 如果可以的话,那就很好了。 (请注意,这里出现了“安全”部分-您是否正确地保护对象以供跨线程使用?)

如果不正常,则应将消息运送到另一个线程进行处理。

对于我和我的房子,我们更喜欢使用Active Object模式来保持IO服务的响应速度,并将多线程担忧降至最低。 请参阅Herb Sutter的有效并发系列文章。 具体来说,您应该阅读:

PS,如果可能的话,请放弃boost::bind()以支持C ++ 11/14 lambda。


更新 :至于为什么更喜欢lambda,答案归结为清晰和可维护性(性能大致相同 ,lambda略有优势)。 一旦您习惯了使用lambda语法进行捕获,而后又不怎么做,它就会自然得多。 Bind要求“从内而外”阅读它,从心理上进行解析永远不会变得很自然,并且对于成员函数和捕获引用更加乏味。 考虑(改编自Boost docs ):

struct S
{
    void foo( int&, double ) const;
} s;

// ...
auto x      = 0;
auto binder = bind( &S::foo, s, ref(x), placeholder::_1 ); // s.foo(x-as-ref, _1)
auto lambda = [&]( auto d ) { s.foo( x, d ); };

auto d = 42.0;
binder( d );
lambda( d );

底部的调用语法是相同的,但lambda定义对于实际发生的事情要清晰得多。 Lambda也可以轻松扩展为多个语句,而bind则不能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM