【发布时间】:2011-05-18 18:17:35
【问题描述】:
我有一个使用 io_service 和多个线程的程序。
它实例化了一些套接字对象。这些对象每个都有一个同步链。所有对 async_read()、async_write() 和类似函数的调用都通过 strand_.wrap(boost::bind(...))。每个对象还有一个 int interlock_ 变量,初始化为 0。
在这些函数之一(on-data-receive 回调)中,我执行以下操作:
Class::startRead(...)
{
...
boost::asio::async_read(socket_, boost::asio::buffer(ptr, 16384), boost::asio::transfer_at_least(1),
strand_.wrap(boost::bind(&EagerConnection::on_read, this, placeholders::error, placeholders::bytes_transferred)));
}
Class::on_read(...)
{
...
startRead();
assert(0 == __sync_fetch_and_add(&interlock_, 1));
onData_();
assert(1 == __sync_fetch_and_add(&interlock_, -1));
}
因为一切都是通过链同步的,所以第一个断言永远不应该触发。不过,确实火了!当我在 GDB 中查看值时,interlock_ 的最终值为 2,这意味着对 on_read() 的两个单独调用同时处于活动状态。
这是否意味着 boost::asio::strand 坏了? (我已经检查过我在完成函数中没有任何重入——onData_ 信号处理程序不会重新调用 on_data())。
“早期”的 startRead 会以某种方式导致立即重新进入吗? (async_x 和 strand 的语义似乎都表明它不能)
如果您真的非常想查看课程的完整内容,可以将其作为要点:https://gist.github.com/979212
【问题讨论】:
标签: multithreading ubuntu boost g++ boost-asio