Boost logo

Boost :

Subject: Re: [boost] [thread] terminating destructor
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2012-10-13 11:43:14


Le 13/10/12 16:08, Andrzej Krzemienski a écrit :
>> std::future does
>>> join without interruption. What does boost::future do? I think it should
>>> interrupt and join (or perhaps detach as per N3451).
>>>
>>> I don't understand this. Could you clarify?
> Sorry, I tried to say too much in one sentence. While std::thread's
> destructor terminates for joinable thread, std::future's destructor sort-of
> joins with the (implied) thread: it waits until the job is done. So we
> already have a potentially surprising suspension upon leaving the scope.
I guess you are referring to the case the std::future is created by async

 0.

    If the implementation chooses the launch::async policy,

      *

        — a call to a waiting function on an asynchronous return object
        that shares the shared state created

        by this async call shall block until the associated thread has
        completed, as if joined (30.3.1.5);

C++ International Standard Otherwise

~std::future();
Effects:
— releases any shared state (30.6.4);
— destroys *this.

Could you explain me what waiting function is called on the future
destructor that needs to block until the completion of the associated
thread?
> I
> guess this is more acceptable for a higher level abstraction. Now, for
> boost::future, I could not figure out what it does in the destructor, but
> if it tries to follow std::future, it probably joins.
I don't know if the current Boost.Thread async implementation is not
conforming to the preceding point in the standard. That is, the shared
state waiting functions don't takes in account whether the future has
been created using async or not, they just block until the shared state
is ready. I find troubling and I don't understand completely why the
committee has changed the semantic of the future operations on the
definition of a free function like async. I need to check the reason the
the committee had to do it this way. Maybe you could help me.

> In the case of the
> future, interruption appears even more appealing because you join anyway,
> and you can only speed the waiting up.
>
> Then I referred to paper N3451 ("async and ~future"):
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3451.pdf
> Herb Sutter observes that because future's destructor blocks, the following
> code:
I'm surely missing something in the standard. Could you explain why the
future's destructor shall block?
> {
> async( []{ f(); } );
> async( []{ g(); } );
> }
>
> surprisingly, is executed synchronously (i.e., we do not launch the task
> executing g() until the task executing f() has finished). He proposes a
> change to std::future to detach in destructor. I just mention it because if
> boost::future tries to follow std::future, this may become necessary one
> day.

Maybe yes, maybe not. Note that N3451 is a proposal and has not been
adopted. I'm not sure this will be accepted (see the thread
[c++std-lib-33127] Re: Herb's paper N3451 on std::async and ~future).

Anyway I need to understand better why the standard recommends to join
the associated thread for the waiting operations.

Best,
Vicente


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