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

Destroying server instance : ASIO C++

本文关键字:ASIO C++ 实例 服务器      更新时间:2023-10-16

引用HTTP服务器-单线程实现我正在尝试显式控制服务器实例的生存期

我的要求是:

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:对于需求2),我需要multiple server instances,我认为我需要在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);
    }

我无法拨打server::handle_stop()

正如您所说,run()在服务停止或工作耗尽之前不会返回。之后再打stop()就没有意义了。

在单线程程序中,您可以从I/O处理程序调用stop()——例如,您可以使用deadline_timer在三秒后调用它。或者你可以用poll()而不是run()做一些复杂的事情,但我不建议这样做。

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

对于[多个服务器],我认为我需要在主中创建一个io_service实例

是的,这可能是最好的做法。

每个进程只能有一个io_service实例是强制性的,还是我可以有多个?

你可以随心所欲。但我认为在一个线程上一次只能运行一个,所以在一个单线程程序中有多个是很棘手的。我会有一个所有服务器都可以使用的实例。

  1. 你是对的,它不起作用,因为你在阻塞run之后调用stop,并且run阻塞,直到出现一些未处理的回调。有多种方法可以解决这个问题,这取决于程序stop的哪一部分将被称为:
    • 若您可以从另一个线程调用它,那个么在单独的线程中运行服务器的每个实例
    • 例如,如果您需要在一些IO操作后停止server,您可以简单地按照尝试过的io_service_.post(boost::bind(&server::handle_stop, this));进行操作,但它应该从另一个线程或从当前线程中的另一个回调进行注册
    • 您可以使用io_service::poll()。它是run的非阻塞版本,所以您创建了一个循环,在需要停止服务器之前调用poll
  2. 你可以双管齐下。即使使用您提供的链接,您也可以查看:
    • HTTP服务器3-An HTTP server using a single io_service and a thread pool
    • 和HTTP服务器2-An HTTP server using an io_service-per-CPU design