我可以在异步io_machine中阻塞I / O吗?

时间:2011-06-28 19:17:56

标签: c++ boost-asio

我有一台服务器,当前正在使用异步IO来(1)接受来自cin的数据并通过UNIX套接字发送该输入,以及(2)接受UNIX套接字上的数据,解析该数据并发回响应。 / p>

当我解析数据时,如何阻止解析器中出现的I / O(下例中的ParseJSON(data_.data()))?在返回parsed async_write之前,它应该通过cin提出问题并收集这些问题的答案;目前,问题已打印出来,但在将答案输入cin之前会发送响应。

socket_是来自stream_protocol::socket的{​​{1}},FWIW。

boost::asio

ParseJSON中发生的缩写版本(某些字符串替换为<>用于保密):

void handle_read(const boost::system::error_code& error,
                 size_t bytes_transferred)
{
    if (!error)
    {
        string parsed = ParseJSON(data_.data());
        async_write(socket_,
            buffer(parsed),
            boost::bind(&session::handle_write,
                shared_from_this(),
                placeholders::error));
    }
}

void handle_write(const boost::system::error_code& error)
{
    if (!error)
    {
        socket_.async_read_some(buffer(data_),
            boost::bind(&session::handle_read,
                shared_from_this(),
                placeholders::error,
                placeholders::bytes_transferred));
    }
}

1 个答案:

答案 0 :(得分:1)

如果ParseJSON()cin进行阻止性读取,那么它将阻止这意味着handle_read()async_write()返回之前不会执行ParseJSON()

我认为问题是parsed是一个堆栈变量。 handle_read()很可能在数据实际写入之前返回,parsed将被销毁。在调用完成处理程序(async_write())之前,传递给handle_write的数据必须有效。

如果handle_read()handle_write()是成员函数,您可以添加parsed成员来保存数据。或者,您可以将parsed包装在绑定到handle_write()的shared_ptr中,如下所示:

void handle_read(const boost::system::error_code& error,
                 size_t bytes_transferred)
{
    if (!error)
    {
        string *ps = new string(ParseJSON(data_.data()));
        boost::shared_ptr<string> pParsed(ps);
        async_write(socket_,
            buffer(*pParsed),
            boost::bind(&session::handle_write,
                shared_from_this(),
                pParsed,
                placeholders::error));
    }
}

void handle_write(boost::shared_ptr<string> pParsed, 
                  const boost::system::error_code& error)
{
    if (!error)
    {
        socket_.async_read_some(buffer(data_),
            boost::bind(&session::handle_read,
                shared_from_this(),
                placeholders::error,
                placeholders::bytes_transferred));
    }
}

当完成处理程序退出时,对shared_ptr的最后一个引用将消失,ps将被销毁。