我是c++ asio的初学者,发现io_service的使用方式非常令人困惑。
我对io_service的理解是它是一个任务队列。和python一样,你可以使用:
asyncio.gather(*[task1, task2...])
将你的任务放到这个队列中,然后运行循环。
然而,在c++中,io_service被用作传递给其他事物的参数。
示例如下https://www.boost.org/doc/libs/1_76_0/doc/html/boost_asio/tutorial.html。io_service用作传递给对象或函数的参数,如下所示。它被传递给计时器:
boost::asio::io_context io;
boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));
或
boost::asio::io_context io_context;
tcp_server server(io_context);
我的问题是,为什么这样做?将io_service传递给函数或对象,但传递的io_service保存任务,这有什么神奇之处?例如,计时器任务现在在io_service的队列中。
如果我要定义一个自定义函数可能使用opencv读取图像,而不是在asio,定时器套接字等预定义的任务。我应该如何创建接受io_service作为参数的对象或函数?谢谢你的帮助!
在过去的几年中,您实际上可以传递执行器,这比传递对您的服务的引用要好得多。所以,还是那样做吧。
一般来说,这个原则被称为依赖注入,不管具体的接口是什么,你都需要它。
最后,选择自由函数而不是成员操作是一个明显的python风格的选择,这在传统的面向对象编程语言中很少见。例如,鼓励你写
post(executor, task);
不是
executor.post(task);
非常类似于python模式,例如你说str(obj)
和len(obj)
而不是obj.str()
或obj.len()
。
注意c++增加了更多的余地,如果任务有关联的执行器,您可以简单地说
post(task);
它的行为相当于post(get_associated_executor(task), task));
查看更多背景:
- 何时必须通过io_context来boost::asio::spawn?(c++)
- std::boost::asio::post/dispatch使用哪个io_context ?