我有一个当前使用异步 IO 的服务器来 (1) 从 cin 接受数据并通过 UNIX 套接字发送该输入,以及 (2) 在 UNIX 套接字上接受数据,解析该数据,并发回响应。
当我解析数据时,如何阻止解析器中发生的 I/O(下例中的 ParseJSON(data_.data())
)?在为 async_write
返回 parsed
之前,它应该通过 cin 提出问题并收集这些问题的答案;目前,打印问题,但在将答案输入 cin 之前发送响应。
socket_
是来自 boost::asio
的 stream_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/