2

Sorry to interrupt, I am a newbie in C++ and Asio...

I just come from here Asio difference between prefer, require and make_work_guard.

I am trying to make a "dummy work" for my io_context.

It is really confusing to a beginner who just wants to make a simple "UDP socket".

The ancient book from Packt and Youtube (https://www.youtube.com/watch?v=2hNdkYInj4g&t=2292s) tutorial tells me to use "work()", the old document tell me to use a much more complex class called "excutor_work_guard", and the new fashion document just tell me to use something extremely unreadable "require()"...

Could I just use "make_work_guard()" and forget about everything else?

Sorry for my English...

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60

1 Answers1

0

As you state yourself, this is a full duplicate of the linked question.

The answer there answers every point you make here.

The ancient book from Packt and Youtube (https://www.youtube.com/watch?v=2hNdkYInj4g&t=2292s) tutorial tells me to use "work()"

I have bad experiences with Packt books on Asio¹. Regardless, there was never a function work(). You probably meant

boost::asio::io_service svc;
boost::asio::io_service::work work(svc);

The newer interface is indeed

boost::asio::io_context ioc;
auto work = make_work_guard(ioc);

That's it.

and the new fashion document just tell me to use something extremely unreadable "require()"...

I have never (ever) seen that anywhere. Can you point me to the place where you found that? In fact, as the linked answer points out, it can be a bad idea to tie work to executors, because it spreads by copying, losing control and inviting deadlocks.

Could I just use "make_work_guard()" and forget about everything else?

Yeah. That's what the other answer already said. If you're in doubt, just re-read the summary there :)


¹ e.g. see Crash : terminate called after throwing an instance of 'std::system_error' what(): Resource deadlock avoided

sehe
  • 374,641
  • 47
  • 450
  • 633
  • https://www.boost.org/doc/libs/1_78_0/doc/html/boost_asio/reference/io_context.html You will find that they use "require()" at the button of that page, "make_work_guard()" became an "old" way to do it. – potter john Mar 20 '22 at 15:42
  • Mmm. Yeah I see now. I feel that's problematic for all the reasons I analyzed in the linked answer. In fact, they even highlight the problems themselves! [the application will then need to call the io_context object's stop() member function](https://www.boost.org/doc/libs/1_78_0/doc/html/boost_asio/reference/io_context.html#:~:text=the%20application%20will%20then%20need%20to%20call%20the%20io_context%20object%27s%20stop()%20member%20function) ... – sehe Mar 20 '22 at 17:34
  • which then leads to the very questionable workaround of [\[store\] the work-tracking executor in an any_io_executor object, so that it may be explicitly reset](https://www.boost.org/doc/libs/1_78_0/doc/html/boost_asio/reference/io_context.html#:~:text=store%20the%20work%2Dtracking%20executor%20in%20an%20any_io_executor%20object%2C%20so%20that%20it%20may%20be%20explicitly%20reset). In my book using `stop()` on an io service is a design smell. It without fail leads to problems. The only reason I use it is to forceful shutdown after a timeout (i.e. programming error or malicious clients) – sehe Mar 20 '22 at 17:34
  • I will probably seek some more information about this change in documentation. It may be a side effect of standardization efforts, but I feel it's going the wrong way, indeed, highly complicating the use for no gain. – sehe Mar 20 '22 at 17:37
  • I feel it's going the wrong way too! It is becoming more and more complex every time they update the Asio! – potter john Mar 21 '22 at 00:56
  • Strong disagree (and I have some experience). The (relatively) new executors are absolutely godsend. No more icking about with `get_io_service` or passing around, no more forgetting/assuming about invocation requirements (like strand wrapping), not even having to supply the token anymore, e.g. `use_future.as_default_on(myobject)` and you can just enjoy life with simple code. Also the improvements in callback signatures (e.g. https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/MoveAcceptHandler.html) in combination with executors, totally rocks. – sehe Mar 21 '22 at 01:13
  • Even the `require`/`prefer` etc. machinery is very cool from a design perspective (akin to a thing like `tag_invoke`, for example). It's just that in that particular page they accidentally focused on the implementation details which, IMO, should not concern people other than library designers. It is all tons better than before, and makes for much easier, less error prone code. Just use `make_work_guard` (oh, another thing that got vastly improved! No more need to muck with `unique_ptr`/`optional` just to get the `reset()` functionality, which you **always** need.) – sehe Mar 21 '22 at 01:15
  • I too suffer from the "Who Moved My Cheese" anguish, and for one thing it makes answering questions a lot harder for some periods of time, because people are all using conflicting versions/are in the process of upgrading. But I do not feel it is all going the wrong way. Thanks for bringing that change in the documentation to my attention. I didn't spot that earlier. – sehe Mar 21 '22 at 01:18
  • Sorry, I will use the make_work_guard... I just want to know some details about why I should use it and why the document recommends a new fashion way but is not very friendly to a newbie... – potter john Mar 21 '22 at 01:31
  • More details? I'm not sure you need those. It's not an issue. Did you also see that executor_work_guard is deprecated? Then you would have something to worry about. – sehe Mar 21 '22 at 08:29