为什么我们需要在boost中使用io_service?

时间:2016-09-17 18:25:59

标签: c++ networking boost boost-asio

我正在尝试学习Boost.asio库。 现在我可以创建一个可以进行通信的客户端和服务器。

为什么我们需要定义一个io_service对象?因为如果这是套接字可用于注册/与底层操作系统通信的唯一对象类型,为什么我们必须无论如何都要定义它。套接字不能自动猜出来吗?我在这里缺少什么?

2 个答案:

答案 0 :(得分:9)

你反向发现为什么单身人士不好吗?那是你的答案。

完成后,处于控制之中并决定在Asio中的服务之间共享多少资源。

因此,您现在可以

  • 在您的应用程序中使用Asio,即使您链接的其中一个库也使用它
  • 每个线程使用一个服务的Asio(因此没有共享状态)或每个服务有多个线程

答案 1 :(得分:2)

boost :: asio :: io_service是任何asio相关应用程序的核心部分,提供两个角色:

  1. 这是一个功能对象的队列。您甚至可以在非网络相关软件中使用它,如下所示:

    void func1(){    //做一点事 } void func2(int x){     //使用x做其他事情 }

    int main(){     boost :: asio :: io_service io;     io.post(func1的);     io.post(boost :: bind(func2,123));     io.run(); }

  2. 这个代码示例将在您调用io.run()时按顺序执行这两个函数 - 而不是在发布期间。发布到io_service只是一个enque操作。 您可能想知道为什么这可能有用。答案是,在这个微不足道的例子中显然不是。但是如果你认为同一个io_service实例的方法run()可以同时被两个或多个线程调用,那么你最终会得到一个模型,其中多个线程可以充当其他线程生成的工作项的工作者。这是一个非常强大的想法,可以促进多线程。

    1. 这是一个选择循环:在网络应用程序中,您可能需要处理大量代表套接字的文件描述符。传统上,这是在一个或多或少看起来像这样的while循环中完成的: while(!done){ //检查哪些文件描述符是可读的或可写的 - 这是通过poll(),select()等完成的 //为每个可读文件描述符:读入一些缓冲区并处理接收到的字节 //为每个可写文件描述符:写入该描述符的任何挂起字节 - 如果有的话。 }
    2. 所以,每次你打电话的时候都会这样:

      boost::asio::async_read(my_asio_socket, my_buffer, boost::bind(my_callback,...))
      

      真正发生的是底层描述符将通过select()机制进行测试以确保可读性。当描述符变得可读时,数据将存储在my_buffer中,当缓冲区变满时,通过bind(...)构造的函数对象将被插入到io_service的函数对象队列中。因此,正在执行my_io_service.run()的线程将被唤醒并执行此回调。

      请注意,多个线程不是必需的。您仍然可以使用主线程,如第一个示例中所示。只要io_service可以帮助将负载分配给多个线程,如果你以这种方式设计应用程序。

      希望这有帮助。