简体   繁体   English

增强ASIO阻止回调

[英]Boost ASIO blocking callbacks

Is it safe (or reasonable) for a the callback from asio to block? 从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(...);
}

Or should I spawn a thread in callback, then return immediately and do operations when that thread is done? 还是应该在回调中生成线程,然后立即返回并在该线程完成后执行操作?

Yes, it is reasonable in many scenarios. 是的,在许多情况下都是合理的。 But you as the architect are responsible for deciding if it is actually reasonable in your scenario. 但是,作为架构师,您有责任确定在您的情况下这是否合理。

Generally speaking, your io_service will run on one thread, and that is the thread it will invoke your callback on, which means it is not processing messages while it is invoking the callback. 一般而言,您的io_service将在一个线程上运行,即它将在其上调用回调的线程,这意味着它在调用回调时未处理消息。 If that's okay, then you're good to go. 如果可以的话,那就很好了。 (Note that the "safe" part comes up here -- are you properly protecting your objects for use across threads?) (请注意,这里出现了“安全”部分-您是否正确地保护对象以供跨线程使用?)

If it's not okay, then you should ship off the message to another thread for processing. 如果不正常,则应将消息运送到另一个线程进行处理。

As for me and my house, we prefer the Active Object pattern to keep the IO service responsive and the multithreading worries to minimum. 对于我和我的房子,我们更喜欢使用Active Object模式来保持IO服务的响应速度,并将多线程担忧降至最低。 See Herb Sutter's article series on Effective Concurrency . 请参阅Herb Sutter的有效并发系列文章。 Specifically, you should read: 具体来说,您应该阅读:

PS, If at all possible, drop boost::bind() in favor of C++11/14 lambdas. PS,如果可能的话,请放弃boost::bind()以支持C ++ 11/14 lambda。


Update : As for why to prefer lambdas, the answer boils down to clarity and maintainability (performance is about the same , with a slight edge for lambdas). 更新 :至于为什么更喜欢lambda,答案归结为清晰和可维护性(性能大致相同 ,lambda略有优势)。 Once you are used to the lambda syntax for capture and what not, it is much more natural. 一旦您习惯了使用lambda语法进行捕获,而后又不怎么做,它就会自然得多。 Bind requires reading it "inside out", never becomes natural to parse mentally, and is even more tedious for member functions and capturing references. Bind要求“从内而外”阅读它,从心理上进行解析永远不会变得很自然,并且对于成员函数和捕获引用更加乏味。 Consider (adapted from the Boost docs ): 考虑(改编自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 );

The call syntax at the bottom is same, but the lambda definition is much clearer as to what's actually happening. 底部的调用语法是相同的,但lambda定义对于实际发生的事情要清晰得多。 Lambdas also easily expand to multiple statements, whereas bind does not. Lambda也可以轻松扩展为多个语句,而bind则不能。

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

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