我是否因为我的提升asio async_read而遇到了竞争状态?

时间:2011-05-31 05:51:06

标签: c++ boost boost-asio race-condition

bool Connection::Receive(){
    std::vector<uint8_t> buf(1000);
    boost::asio::async_read(socket_,boost::asio::buffer(buf,1000),
            boost::bind(&Connection::handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));

    int rcvlen=buf.size();
    ByteBuffer b((std::shared_ptr<uint8_t>)buf.data(),rcvlen);
    if(rcvlen <= 0){
        buf.clear();
        return false;
    }
    OnReceived(b);
    buf.clear();
    return true;
}

该方法工作正常,但只有当我在其中创建断点时。等待接收的时间是否存在问题?没有断点,没有收到任何信息。

1 个答案:

答案 0 :(得分:4)

您正在尝试在启动异步操作后立即从接收缓冲区读取,而不是等待它完成,这就是设置断点时它的工作原理。

async_read之后的代码属于Connection::handler,因为这是您在收到一些数据后告诉async_read调用的回调。

您通常需要的是start_readhandle_read_some功能:

void connection::start_read()
{
    socket_->async_read_some(boost::asio::buffer(read_buffer_),
        boost::bind(&connection::handle_read_some, shared_from_this(),
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
}

void connection::handle_read_some(const boost::system::error_code& error, size_t bytes_transferred)
{
    if (!error)
    {
        // Use the data here!

        start_read();
    }
}

请注意shared_from_this,如果您希望连接的生命周期由未完成的I / O请求数自动处理,这一点很重要。请务必从boost::enable_shared_from_this<connection>派生您的课程,并仅使用make_shared<connection>创建课程。

要强制执行此操作,您的构造函数应该是私有的,您可以添加一个朋友声明(C ++ 0x版本;如果您的编译器不支持此功能,则必须自己插入正确数量的参数):

template<typename T, typename... Arg> friend boost::shared_ptr<T> boost::make_shared(const Arg&...);

还要确保在调用回调时接收缓冲区仍处于活动状态,最好使用连接类的静态大小的缓冲区成员变量。