簡體   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