boost asio“数据库查找期间发生了不可恢复的错误”

时间:2011-09-06 11:32:38

标签: c++ boost boost-asio

我目前正在对我的服务器进行压力测试。

有时我会收到“数据库查找期间发生不可恢复的错误”错误 来自 error.message()

通过 async_read方法调用 boost :: asio :: placeholders :: error

错误发送到我的处理函数。

我不知道这个错误意味着什么,我无法故意重现这个错误,它有时只会发生并且似乎是随机的(当然不是,但似乎)

有没有人收到此错误消息,如果有,请知道它来自哪里?


编辑1

这是我在boost库中找到的,错误是:

no_recovery = BOOST_ASIO_NETDB_ERROR(NO_RECOVERY)

但无法弄清楚这是什么......


编辑2

只是让你知道我的问题的一切,这里的设计:

我只有一个io_service。 每次用户连接时,都会启动async_read,等待读取内容。 当它读取内容时,大多数时候,它在一个线程(来自池)上做一些工作,并将某些内容同步写回用户。 (使用boost写入)。 即使因为1.37提升声称同步写入是线程安全的,我真的很担心它会来自这个。

如果用户真的快速发送不同的消息,可能会同时调用async_read和write,它会不会造成任何伤害?


编辑3

以下是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 。因此我首先担心。

1 个答案:

答案 0 :(得分:0)

  

当它读取某些内容时,大多数时候,它正在做一些工作   线程(来自池),并同步写回东西   用户。 (使用boost写入)。 即便提升1.37声称   同步写是线程安全的,我真的很担心这个事实   它来自于此。

我强调,这是不正确的。单个boost::asio::tcp::socket不是线程安全的,documentation非常明确

  

线程安全

     

不同的对象:安全。

     

共享对象:不安全。

async_read()与阻止write()混合在一起也很奇怪。