c++ - 在单独的线程中正确使用 Boost::asio

标签 c++ multithreading boost boost-asio

我正在为Orbiter space simulator编写一个DLL插件。 ,它允许与外部系统进行 UDP 通信。我选择 boost::asio 来完成这项任务,因为它允许我从低级内容中抽象出来。

“边界条件”如下:

  1. 我可以从我的 DLL 创建任何线程或调用任何 API 函数
  2. 由于缺乏其他线程安全性,我只能在传递给 DLL(每帧)的回调内修改模拟内部的数据。

因此,我为用于通信的 NetworkClient 类选择了以下架构:

  • 构建后,它会初始化 UDP 套接字 (boost::socket+boost::io_service) 并启动一个线程,该线程调用 io_service.run()
  • 传入消息异步放入队列(通过 CriticalSection 实现线程安全)
  • 回调处理函数可以从队列中拉取消息并进行处理

但是,我在运行实现时遇到了一些奇怪的异常: boost::exception_detail::clone_impl > 位于内存位置 0x01ABFA00。

io_service.run()调用时出现异常。

有人可以指点我吗,我错过了什么吗?我的类(class)的代码 list 如下。

网络客户端声明:

class NetworkClient {
public:
    NetworkClient(udp::endpoint server_endpoint);
    ~NetworkClient();

    void Send(shared_ptr<NetworkMessage> message);
    inline bool HasMessages() {return incomingMessages.HasMessages();};
    inline shared_ptr<NetworkMessage> GetQueuedMessage() {return incomingMessages.GetQueuedMessage();};

private:
    // Network send/receive stuff
    boost::asio::io_service io_service;
    udp::socket socket;
    udp::endpoint server_endpoint;
    udp::endpoint remote_endpoint;
    boost::array<char, NetworkBufferSize> recv_buffer;

    // Queue for incoming messages
    NetworkMessageQueue incomingMessages;

    void start_receive();
    void handle_receive(const boost::system::error_code& error, std::size_t bytes_transferred);
    void handle_send(boost::shared_ptr<std::string> /*message*/, const boost::system::error_code& /*error*/, std::size_t /*bytes_transferred*/) {}
    void run_service();

    NetworkClient(NetworkClient&); // block default copy constructor
};

方法实现:

NetworkClient::NetworkClient(udp::endpoint server_endpoint) : socket(io_service, udp::endpoint(udp::v4(), 28465)) {
    this->server_endpoint = server_endpoint;
    boost::thread* th = new boost::thread(boost::bind(&NetworkClient::run_service,this));
    start_receive();
}

void NetworkClient::start_receive()
{
    socket.async_receive_from(boost::asio::buffer(recv_buffer), remote_endpoint,
        boost::bind(&NetworkClient::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)
    );
}
void NetworkClient::run_service()
{
    this->io_service.run();
}

最佳答案

据我所知,您的架构没有任何问题。您应该捕获从 io_service::run() 抛出的异常,这可能是问题的根源。

void NetworkClient::run_service()
{
    while(1) {
        try {
            this->io_service.run();
        } catch( const std::exception& e ) {
            std::cerr << e.what << std::endl;
        }
    }
}

您还需要修复引发异常的任何内容。

关于c++ - 在单独的线程中正确使用 Boost::asio,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14304660/

相关文章:

c++ - Qt QList - removeAll 释放内存

C++编译器不识别头文件

c++ - 终止正在运行的 boost 线程

c++ - 数据结构设计模式

未捕获 C++ 异常,程序终止并中止

c++ - 互斥条件信令循环如何工作?

Java 2D 游戏 - MouseClicked 和 MouseMoved 方法

c++ - 使用 Boost 状态图,如何无条件转换到状态?

c++ - 在 for_each 中使用变换 boost fusion

c++ - 在 constexpr 中将 `void*` 转换为 `unsigned int`