[英]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.