【问题标题】:How to run io_service in other thread?如何在其他线程中运行 io_service?
【发布时间】:2016-05-22 16:19:45
【问题描述】:

我正在尝试运行 udp 服务器。问题是阻塞 io_service 上的 run() 调用。 所以我决定使用 boost bind 在其他线程上运行这个方法。 结果主线程执行超出了 DictionaryImpl 构造函数范围,但是当我发送 udp 包时,tcpdump 告诉我我的端口无法访问。 当我在主线程中调用 io_service 上的 run() 调用时,一切正常。 问题出在哪里?

class DictionaryImpl  {
    boost::asio::io_service io;
    boost::scoped_ptr<boost::thread> thread;

public:
    DictionaryImpl() {
        try {
            udp_server2 udpReceiver(io);

            thread.reset(new boost::thread(
                    boost::bind(&DictionaryImpl::g, this, std::ref(io))));

        } catch (std::exception &e) {
            std::cerr << "Exception: " << e.what() << "\n";
        }

    }

    void g(boost::asio::io_service & io){
        io.run();
    }

    virtual ~DictionaryImpl() {
        if (!thread) return; // stopped
        io.stop();
        thread->join();
        io.reset();
        thread.reset();
    }

};






class udp_server2
{
public:
    udp_server2(boost::asio::io_service& io_service)
            : socket_(io_service, udp::endpoint(udp::v4(), 13003))
    {
        start_receive();
    }

private:
    void start_receive()
    {
        socket_.async_receive_from(
                boost::asio::buffer(recv_buffer_), remote_endpoint_,
                boost::bind(&udp_server2::handle_receive, this,
                            boost::asio::placeholders::error,
                            boost::asio::placeholders::bytes_transferred));
    }

    void handle_receive(const boost::system::error_code& error,
                        std::size_t /*bytes_transferred*/)
    {
        if (!error || error == boost::asio::error::message_size)
        {
            std::cout<<"handle_receive\n";    
            start_receive();
        }
    }



    udp::socket socket_;
    udp::endpoint remote_endpoint_;
    boost::array<char, 1> recv_buffer_;
};

【问题讨论】:

标签: c++ boost udp boost-asio


【解决方案1】:

DictionaryImpl 的 io_service 将在工作结束时停止。您可以使用asio::io_service::work 来防止这种情况发生。

~DictionaryImpl 中,您在io_service 上调用stop 之后调用reset。如果您打算随后重新启动 io_service,您唯一需要这样做。

看起来你会从重新访问文档中受益(我接受它有点稀疏)。还可以查看 asio 文档中的多线程示例。他们将展示使用 work 对象的示例。

【讨论】:

    猜你喜欢
    • 2014-12-18
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    相关资源
    最近更新 更多