c++ - 我可以在异步 io_machine 中使用阻塞 I/O 吗?

标签 c++ boost-asio

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

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

socket_ 是来自 boost::asiostream_protocol::socket,FWIW。

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));
    }
}

ParseJSON 中发生的事情的缩略版(一些字符串替换为 <> 以保密):

string ParseJSON(string input)
{
    int status;
    string toWrite;

    JSONNode parsed = libjson::parse(input);
    JSONNode::const_iterator iter = parsed.begin(); 
    json_string node_name = iter -> as_string();

    if (node_name.compare("<>") == 0)   
    {
        cout << "<>" << endl;
        cout << "<>";
        cout.flush();
        cin >> status;

        JSONNode n(JSON_NODE);
        n.push_back(JSONNode("<>","<>"));
        JSONNode c(JSON_NODE);
        c.set_name("args");
        c.push_back(JSONNode("<>",status));
        n.push_back(c);
        toWrite = n.write();
        return toWrite;
    }
}

最佳答案

如果 ParseJSON()cin 执行阻塞读取,那么它将阻塞,这意味着 handle_read() 不会执行 async_write() 直到 ParseJSON() 返回。

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

如果 handle_read()handle_write() 是成员函数,您可以添加一个 parsed 成员来保存数据。或者,您可以将 parsed 包装在绑定(bind)到 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 将被销毁。

关于c++ - 我可以在异步 io_machine 中使用阻塞 I/O 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6511942/

相关文章:

c++ - 使用Boost序列化和发送数据结构?

c++ - 试图用 boost::asio::async_read 替换我的 boost::asio::read

c++ - 获取指向 boost::any 内容的 void* 指针

c++ - 通过重复生成所有排列

c++ - Git 状态显示奇怪的未跟踪 "path_of_file\r"文件,如何通过命令行删除

c++ - boost asio取消读取而不取消写入

c++ - 用于 ASIO 写入的十六进制字符串到字节

c++ - 销毁时神秘的段错误

c++ - 渲染各向异性纹理的更快方法?

c++ - 带有 Boost.Asio 的数据报 Unix 域套接字