我目前正在对我的服务器进行压力测试。
有时我会收到“数据库查找期间发生不可恢复的错误”错误 来自 error.message()
通过 async_read方法调用 boost :: asio :: placeholders :: error 将错误发送到我的处理函数。
我不知道这个错误意味着什么,我无法故意重现这个错误,它有时只会发生并且似乎是随机的(当然不是,但似乎)
有没有人收到此错误消息,如果有,请知道它来自哪里?
这是我在boost库中找到的,错误是:
no_recovery = BOOST_ASIO_NETDB_ERROR(NO_RECOVERY)
但无法弄清楚这是什么......
只是让你知道我的问题的一切,这里的设计:
我只有一个io_service。 每次用户连接时,都会启动async_read,等待读取内容。 当它读取内容时,大多数时候,它在一个线程(来自池)上做一些工作,并将某些内容同步写回用户。 (使用boost写入)。 即使因为1.37提升声称同步写入是线程安全的,我真的很担心它会来自这个。
如果用户真的快速发送不同的消息,可能会同时调用async_read和write,它会不会造成任何伤害?
以下是Dave S提出的部分代码:
void TCPConnection::listenForCMD() {
boost::asio::async_read(m_socket,
boost::asio::buffer(m_inbound_data, 3),
boost::asio::transfer_at_least(3),
boost::bind(&TCPConnection::handle_cmd,
shared_from_this(),
boost::asio::placeholders::error)
);
}
void TCPConnection::handle_cmd(const boost::system::error_code& error) {
if (error) {
std::cout << "ERROR READING : " << error.message() << std::endl;
return;
}
std::string str1(m_inbound_data);
std::string str = str1.substr(0,3);
std::cout << "COMMAND FUNCTION: " << str << std::endl;
a_fact func = CommandFactory::getInstance()->getFunction(str);
if (func == NULL) {
std::cout << "command doesn't exist: " << str << std::endl;
return;
}
protocol::in::Command::pointer cmd = func(m_socket, client);
cmd->setCallback(boost::bind(&TCPConnection::command_is_done,
shared_from_this()));
cmd->parse();
}
m_inbound_data是一个char [3]
完成cmd-&gt; parse()后,它将调用回调 command_is_done
void TCPConnection::command_is_done() {
m_inbound_data[0] = '0';
m_inbound_data[1] = '0';
m_inbound_data[2] = '0';
listenForCMD();
}
在第一行检查错误时, handle_cmd 中会出现错误。
正如我之前所说,cmd-&gt; parse()将解析它刚刚获得的命令,有时会在来自池的线程中阻塞代码。在这个线程上,它通过同步写入将数据发送回客户端。
重要事项:在启动上述线程之前,将始终调用回调 command_is_done 。这意味着当线程可能在同步写入中将某些内容发送回客户端时,已经调用 listenForCMD 。因此我首先担心。
答案 0 :(得分:0)
当它读取某些内容时,大多数时候,它正在做一些工作 线程(来自池),并同步写回东西 用户。 (使用boost写入)。 即便提升1.37声称 同步写是线程安全的,我真的很担心这个事实 它来自于此。
我强调,这是不正确的。单个boost::asio::tcp::socket
不是线程安全的,documentation非常明确
线程安全
不同的对象:安全。
共享对象:不安全。
将async_read()
与阻止write()
混合在一起也很奇怪。