jlyw1017
jlyw1017

Reputation: 11

Why is boost::asio::io service designed to be used as a parameter?

I am a beginner in c++ asio and found it very confusing how io_service is used.

My understanding of io_service is that it's a queue of tasks. Like in python you use:

asyncio.gather(*[task1, task2...])

to put your tasks in this queue and then run the loop.

However, in c++ the io_service is used as a parameter to be passed into some other things.

As examples show like here https://www.boost.org/doc/libs/1_76_0/doc/html/boost_asio/tutorial.html. The io_serivce is used as parameter passed to an object or function like here. It is passed to the timer:

  boost::asio::io_context io;

  boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));

or like

    boost::asio::io_context io_context;
    tcp_server server(io_context);

My question would be, why doing so? What's the magic to pass an io_service to a function or object, but the passed io_service holds the task? E.g. the timer task is now in the queue of io_service.

And if I would define a custom function maybe use opencv to read images instead of predefined tasks in asio, timer socket etc. How should I create the object or function which accept io_service as a parameter? Thank you for your help!

Upvotes: 0

Views: 796

Answers (1)

sehe
sehe

Reputation: 393124

In last years, you can actually pass around executors, which is much better than passing around references to your service. So, do that instead.

In general, this principle is known as dependency injection, and you need it in one way or another, regardless of the concrete interface.

Lastly, the choice for free functions instead of member operations is a distinctly Pythonesque choice that is rare among the traditional OO programming languages. The idea that e.g. you are encouraged to write

 post(executor, task);

Instead of

 executor.post(task);

Closely resembles the Pythonesque pattern where you say e.g. str(obj) and len(obj) instead of obj.str() or obj.len().

Note that C++ adds even more leeway, where if the task has an associated executor you can simply say

 post(task);

And it behave equivalent to post(get_associated_executor(task), task));

See more background:

Upvotes: 1

Related Questions