【发布时间】:2016-09-17 18:25:58
【问题描述】:
我正在尝试学习 Boost.asio 库。 现在我可以创建一个可以通信的客户端和服务器了。
为什么我们需要定义一个 io_service 对象?因为如果这是唯一可用于套接字注册/与底层操作系统通信的对象类型,我们为什么还要定义它。插座不能自动猜到吗?我在这里错过了什么?
【问题讨论】:
标签: c++ networking boost boost-asio
我正在尝试学习 Boost.asio 库。 现在我可以创建一个可以通信的客户端和服务器了。
为什么我们需要定义一个 io_service 对象?因为如果这是唯一可用于套接字注册/与底层操作系统通信的对象类型,我们为什么还要定义它。插座不能自动猜到吗?我在这里错过了什么?
【问题讨论】:
标签: c++ networking boost boost-asio
你是否在反向发现单身人士为什么不好?这就是你的答案。
完成后,您可以控制并决定在 Asio 中的服务之间共享多少资源。
因此,您现在可以
等等
【讨论】:
boost::asio::io_service 是任何与 asio 相关的应用程序的核心部分,有两个角色:
这是一个函数对象的队列。你甚至可以在像这样的非网络相关软件中使用它:
void func1() { //做一点事 } 无效 func2(int x) { // 使用 x 做其他事情 }
int main() { boost::asio::io_service io; io.post(func1); io.post(boost::bind(func2, 123)); io.run(); }
此代码示例将在您调用 io.run() 时按顺序执行这两个函数 - 而不是在发布期间。发布到 io_service 只是一个 enque 操作。 您可能想知道为什么这会很有用。答案是,在这个简单的例子中显然不是。但是,如果您认为同一 io_service 实例的方法 run() 可以由两个或多个线程同时调用,那么您最终会得到一个模型,其中多个线程可以充当其他线程生成的工作项的工作人员。这是一个非常强大的想法,可以促进多线程。
所以,每次你调用类似:
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 可以方便地将负载分派到多个线程。
希望这会有所帮助。
【讨论】:
select 阻塞吗?我希望async_read 使用poll 的某种组合
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout );。此外,kqueue、epoll、poll、IO Completion Ports、select 或任何使用的都是实现细节。