[threads] Launch deferred for async

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[threads] Launch deferred for async

Boost - Dev mailing list
Hello all,

I am using boost::async() to create futures from tasks in order to wrap
some behavior that may or may not be sync. This behavior is implemented
behind an interface and can be small and fast operations or longer running
and blocking things. All return a future as a result type, so I can hide
the ugly truth.

For the smaller stuff I'd like to use launch::deferred to avoid threading
altogether and just execute the task when the user get()s the future.

    boost::future<bool> ret = boost::async(boost::launch::deferred, [this]
() -> bool {
        // do some small cpu only impl
        return result;
    });

But when i get the result:

    const bool result = ret.get();

...the application crashes. Debugging this I came to this in
boost/thread/future.hpp:9373

    } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
      std::terminate();
      //BOOST_THREAD_FUTURE<R> ret;
      //return ::boost::move(ret);
      //          return
boost::detail::make_future_deferred_shared_state<Rp>(
      //              BF(
      //                  thread_detail::decay_copy(boost::forward<F>(f))
      //              )
      //          );
    } else {

To me this sounds like the application will always std::terminate() when
launch::deferred is chosen. Why is that?

When I use launch::any it seems to work but why is there a parameter that
always yields unwanted results. What is the reason behind it? Can I get
launch::deferred as it is described (not threading, just executing the task
sync when get() is called) somehow?

Platform is x64 Windows 10, MSVC14.1.

Cheers,
Stephan

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [threads] Launch deferred for async

Boost - Dev mailing list
On 27/11/2018 02:30, Stephan Menzel wrote:

> But when i get the result:
>
>      const bool result = ret.get();
>
> ...the application crashes. Debugging this I came to this in
> boost/thread/future.hpp:9373
>
>      } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
>        std::terminate();
>        //BOOST_THREAD_FUTURE<R> ret;
>        //return ::boost::move(ret);
>        //          return
> boost::detail::make_future_deferred_shared_state<Rp>(
>        //              BF(
>        //                  thread_detail::decay_copy(boost::forward<F>(f))
>        //              )
>        //          );
>      } else {
>
> To me this sounds like the application will always std::terminate() when
> launch::deferred is chosen. Why is that?

This implementation appears to be conditioned on
BOOST_THREAD_PROVIDES_VARIADIC_THREAD -- it's implemented "properly"
when that is defined.

In order to get that defined, you must be using at least a C++11
conformant compiler (and compilation mode) and have explicitly defined
the following in all translation units that use Boost.Thread (prior to
including it):

#define BOOST_THREAD_VERSION 4

(or the equivalent project / command line option).

This also makes Boost.Thread behave a more like std::thread, which might
have other consequences if you were relying on the previous behaviour.

I couldn't find any documentation that explains why this was left
unimplemented for the non-variadic version; presumably there was some
kind of compilation issue, or just an assumption that using new
facilities requires using the latest interface version.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [threads] Launch deferred for async

Boost - Dev mailing list
Hello Gavin,

On Tue, Nov 27, 2018 at 4:06 AM Gavin Lambert via Boost <
[hidden email]> wrote:

>
> > To me this sounds like the application will always std::terminate() when
> > launch::deferred is chosen. Why is that?
>
> This implementation appears to be conditioned on
> BOOST_THREAD_PROVIDES_VARIADIC_THREAD -- it's implemented "properly"
> when that is defined.
>
In order to get that defined, you must be using at least a C++11
> conformant compiler (and compilation mode) and have explicitly defined
> the following in all translation units that use Boost.Thread (prior to
> including it):
>
> #define BOOST_THREAD_VERSION 4
>
>
Ah, this explains it. I have BOOST_THREAD_VERSION 3 explicitly defined
because I couldn't be having with some of the version 4 behavior. Which is
why I prefer boost threads over std threads in the first place.

Thanks for the heads up. I will try to re-evaluate if I should go for
version 4 after all but as I recall there were some strong reasons not to
do it. At least now I know what I'm trading in for that.

Cheers,
Stephan

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [threads] Launch deferred for async

Boost - Dev mailing list
On Tue, Nov 27, 2018 at 7:24 AM Stephan Menzel <[hidden email]>
wrote:

> Ah, this explains it. I have BOOST_THREAD_VERSION 3 explicitly defined
> because I couldn't be having with some of the version 4 behavior. Which is
> why I prefer boost threads over std threads in the first place.
>
> Thanks for the heads up. I will try to re-evaluate if I should go for
> version 4 after all but as I recall there were some strong reasons not to
> do it. At least now I know what I'm trading in for that.
>
>
A little update in case anyone is interested. First of all, going to
version 4 does indeed fix the problem. As to the reasons why I went to
version 3 I have some curious findings.

1)  When using version 4, boost::future<> doesn't exist. I have to use
boost::unique_future<> instead, which is nowhere mentioned in the docs. So
essentially, when I do the examples in the docs, I have to force the
version to 3 or lower or it won't compile. Unless I use shared_future that
is.

2) I have several occurrences of using boost::static_visitor for treating
variants. And I often move the value into there. Like this:

    boost::apply_visitor(my_visitor, std::move(value));

Being seemingly unrelated to boost threads, this won't compile anymore when
I remove threads version 3. I had to remove the std::move() operator. I
have no idea why but the error novel suggests it's got something to do with
boost units being somewhere in the include path. I do use boost units but
nowhere near that apply visitor lines.

I can live with both of these things but they appear very strange to me.

Cheers,
Stephan

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [threads] Launch deferred for async

Boost - Dev mailing list
On 27/11/2018 23:25, Stephan Menzel wrote:
>> Ah, this explains it. I have BOOST_THREAD_VERSION 3 explicitly defined
>> because I couldn't be having with some of the version 4 behavior. Which is
>> why I prefer boost threads over std threads in the first place.
>>
>> Thanks for the heads up. I will try to re-evaluate if I should go for
>> version 4 after all but as I recall there were some strong reasons not to
>> do it. At least now I know what I'm trading in for that.

Sometimes you can enable specific sub-features of a new version while
mostly using the old version, but combinations are probably less well
tested and I would assume there are probably hidden dependencies.

> 1)  When using version 4, boost::future<> doesn't exist. I have to use
> boost::unique_future<> instead, which is nowhere mentioned in the docs. So
> essentially, when I do the examples in the docs, I have to force the
> version to 3 or lower or it won't compile. Unless I use shared_future that
> is.

It should be the other way around -- version 2 (the default) uses
unique_future<> while version 3 and 4 use future<>.

https://www.boost.org/doc/libs/1_68_0/doc/html/thread/build.html#thread.build.configuration.future

It was renamed due to alignment with the C++11 standard.  Alias
templates would have been nice, but I guess Boost.Thread is mostly
targeted at C++03 and those aren't available there anyway.

> 2) I have several occurrences of using boost::static_visitor for treating
> variants. And I often move the value into there. Like this:
>
>      boost::apply_visitor(my_visitor, std::move(value));

I don't think I can help with that one, at least not without more
context. :)

Maybe the rest of the info on that page might help, since it appears you
missed it?

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost