Boost logo

Boost :

Subject: Re: [boost] Asynchronous library now in Boost Library Incubator
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2016-12-04 17:04:21


On 12/04/2016 04:15 PM, Hartmut Kaiser wrote:
>
>>> Future-based designs do not mix well with state machines' run-to-
>> completion.
>>> <
>>>
>>> Could you elaborate a little on that comment please? I have a had a
>> couple of instances where I'm manipulating 'state' and transitioning from
>> one to another - I would welcome some ideas on how to make this a bit
>> cleaner.
>>
>> A future.then() returns another future so isn't it just delaying the
>> fact that I have to decide at some point what to do with the future
>> object? Do I poll it, get() it or ignore it?
>> Polling is tedious, ignore usually wrong, and get() means blocking. As a
>> state machine run-to-completion is supposed to execute in no time, this
>> is not a good option.
>> Run-to-completion means: event is sent, transition is executed. Until it
>> completes, the state machine is in an unstable state. This has to be
>> kept as short as possible.
>
> HPX uses futures as explicit means to express dependencies between tasks

Hartmut, can we leave HPX aside and talk about the library discussed here?

> which allows for asynchronous execution without barriers. Surely, at some
> point you need to call get() on the top-most future representing the whole
> execution tree, but this is usually not an issue as most (if not all)
> applications have natural synchronization points imposed by their
> implemented logic. These future objects are a very useful construct allowing
> to express various kind of asynchrony in an application. But I'm sure you
> agree to that as more than half of the documentation of Boost.Asynchronous
> explains concepts based on using futures as a concept.

Not at all! The first examples are using futures to show that the
library supports futures and as transition to the other, more powerful
parts of the library. The future-based continuations are also provided
for cases where no other possibility is available (external libraries
returning futures).

>>> The reason for the non-blocking focus is that I'm using the library at
>> work in an industrial 24/7 application. When working on the production
>> line, blocking is a disaster. If an algorithm goes astray, or simply takes
>> longer than usually, blocking the production line results in huge costs.
>> Crashes due to races also. Asynchronous provides ways to avoid both.
>
> Using futures, even if you have to call future::get() does not imply
> blocking. It implies possible suspension, which is a completely different
> beast. Calling future::get() on one task does not 'block' the kernel-thread
> running the task as it is now free to run other tasks.

It implies blocking the current thread of execution, at least
std::future. I'm not talking about HPX ones, as I do not know the
library and would prefer to comment only asynchronous and std.
Coming back to my other favorite subject, if a state machine is waiting
on a get(), its run to completion is incorrect and it cannot react to
events.

>>> I would say that non-blocking behaviour is one of the central goals of
>> HPX. Continuations are only triggered when futures become ready and
>> therefore blocking is avoided - so I don't think there's any disagreement
>> there! Races are a problem, but a functional style of programming goes a
>> long way to avoiding them.
>>
>> I agree that HPX likely solves well the race problem, which is a great
>> achievement.
>> I feel both libraries solve quite different problems. Asynchronous is
>> focusing on organizing objects into threads and building everything else
>> on top of that. In that context, callbacks within these object's thread
>> contexts make more sense than a fire-and-forget of a future.then();
>
> Why do you think future::then() is fire& forget?

This is what I understand from reading the description of std
experimental. If future::then is executed by a threadpool thread, it is
not done by the single thread world and a race risk is given in order to
not execute the then part. Am I missing something?

> Future::then is a means of turning a future into a callback, while the
> opposite can be achieved for instance by using a packaged task. So I'd say
> both concepts are equivalent in terms of provided functionality.
>
> The benefit of a future based approach (in my experience) is that it leads
> to a very functional style of programming, while encouraging value
> semantics. Both things naturally support race-free programming... The other
> benefit is that futures very much hide the notion of threads altogether,
> thus exposing higher level abstractions freeing the programmer's mind from
> tracking thousands (or more) execution states at the same time.

In my experience, not everything is functional and not only futures
encourage value semantics. By using a threadpool, one is automatically
encouraged to do so: move into the pool, move back from it.
Asynchronous simply takes another way to these goals. It aims at
race-free programming and hides threads just to a certain point: know
where they are and how many, do not access them directly.
I suppose, some will prefer HPX or std::async style, others
Asynchronous. There are probably many ways to the same goal.

Regards,
Christophe

> Regards Hartmut
> ---------------
> http://boost-spirit.com
> http://stellar.cct.lsu.edu
>
>
>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk