销毁服务器实例:ASIO C ++

时间:2015-02-19 13:35:27

标签: c++ boost-asio

参考HTTP Server- Single threaded Implementation 我试图明确控制服务器实例的生命周期

我的要求是:

1) I should be able to explicitly destroy the server

2) I need to keep multiple Server Instances alive which should listen to different ports

3) Manager Class maintains list of all active server instances; should be able to create and destroy the server instances by create and drop methods

我正在尝试实施要求1 和 我想出了代码:

    void server::stop()
    {
        DEBUG_MSG("Stopped");
        io_service_.post(boost::bind(&server::handle_stop, this));
    }

其中handle_stop()

void server::handle_stop()
    {
        // The server is stopped by cancelling all outstanding asynchronous
        // operations. Once all operations have finished the io_service::run() call
        // will exit.
        acceptor_.close();
        connection_manager_.stop_all();
    }

我尝试将其从main()称为:

try
{
    http::server::server s("127.0.0.1","8973");
    // Run the server until stopped.
    s.run();
    boost::this_thread::sleep_for(boost::chrono::seconds(3));
    s.stop();
}
catch (std::exception& e)
{
    std::cerr << "exception: " << e.what() << "\n";
}

问题1) 我无法拨打server::handle_stop()

我认为io_service_.run()阻止了我的s.stop()来电。

void server::run()
{
    // The io_service::run() call will block until all asynchronous operations
    // have finished. While the server is running, there is always at least one
    // asynchronous operation outstanding: the asynchronous accept call waiting
    // for new incoming connections.
    io_service_.run();
}

我该如何处理?

问题2: 对于我需要multiple server instances的要求2),我想我需要在main中创建io_service instance,并且必须将同一个实例传递给所有server instances。我是对的吗?

每个流程是否必须only one io_service instance或者我可以拥有多个流程吗?

修改

我的目标是实现一个可以控制多服务器实例的类:

下面排序的东西(不正确的代码//只是提供视图,我试图实现)我想实现 - 我该如何设计?

我对io_Service感到困惑,如何干净地致电mng.create()mng.drop()

  Class Manager{
    public:
    void createServer(ServerPtr)
    {
     list_.insert(make_shared<Server> (ip, port));
    }
    void drop()
    {
    list_.drop((ServerPtr));
    }
    private:
    io_service iO_;
    set<server> list_;
    };


    main()
    {
    io_service io;
    Manager mng(io);

    mng.createServer(ip1,port1);
    mng.createServer(ip2,port2);

    io.run();

    mng.drop(ip1,port1);
    }

2 个答案:

答案 0 :(得分:1)

  

我无法拨打server::handle_stop()

正如您所说,run()在服务停止或用完之前不会返回。在那之后调用stop()毫无意义。

在单线程程序中,您可以从I / O处理程序调用{​​{1}} - 例如,您可以使用stop()在三秒钟后调用它。或者您可以使用deadline_timer而不是poll()执行复杂操作,但我不建议这样做。

在多线程程序中,只要确保它是线程安全的,就可以从另一个调用run()的线程调用它。

  

对于[多台服务器],我想我需要在main

中创建一个run()实例

是的,这可能是最好的事情。

  

每个进程只需要一个io_service个实例,或者我可以拥有多个实例吗?

你可以拥有任意数量的人。但我认为你只能在一个线程上一次运行一个,所以在一个单线程程序中有多个是很棘手的。我有一个所有服务器都可以使用的实例。

答案 1 :(得分:1)

  1. 你是对的,因为你在阻止stop之后调用run,并且run阻止,直到有一些未处理的回调,这是行不通的。有多种方法可以解决这个问题,它会从程序stop的哪个部分被调用:
    • 如果您可以从另一个线程调用它,则在单独的线程中运行每个服务器实例。
    • 如果您需要在某些IO操作后停止server,例如您可以按照您尝试io_service_.post(boost::bind(&server::handle_stop, this));进行操作,但应该从另一个线程或当前线程中的另一个回调注册。< / LI>
    • 您可以使用io_service::poll()。它是run的非阻止版本,因此您创建一个循环,在其中调用poll,直到您需要停止服务器。
  2. 你可以两种方式做到。即使您提供的链接,您也可以查看:
    • HTTP Server 3 - An HTTP server using a single io_service and a thread pool
    • HTTP Server 2 - An HTTP server using an io_service-per-CPU design