为什么我可以调用的boost :: unique_future ::获得了很多次,不同的std ::未来? [英] Why can I call boost::unique_future::get many times, unlike std::future?

查看:431
本文介绍了为什么我可以调用的boost :: unique_future ::获得了很多次,不同的std ::未来?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我们不能称之为的std ::未来::获得很多次,我们应该使用的std :: shared_future 如果我们需要调用了很多次。

I know we can't call std::future::get many times, and we should use std::shared_future if we need to call it many times.

但是,我们可以称之为的boost :: unique_future ::获得很多次,虽然有的boost :: shared_future

But we can call boost::unique_future::get many times, although there's boost::shared_future!

void test1()
{
    int i, j;

    std::future<int> fu1 = std::async([]{ return 42; });
    i = fu1.get();
    //j = fu1.get(); // error occur
    std::cout << i << std::endl;

    boost::unique_future<int> fu2 = boost::async([]{ return 43; });
    i = fu2.get();
    j = fu2.get(); // sucess...?
    std::cout << i << ' ' << j << std::endl;

    std::cin.get();
}

输出是:

42
43 43

我想了一会儿,然后尝试这个测试code。

I thought for a moment and then try this test code.

class TestCls
{
public:
    TestCls()
    {
        std::cout << "[TestCls] default constructor" << std::endl;
    }
    TestCls(const TestCls &other)
    {
        std::cout << "[TestCls] copy constructor" << std::endl;
    }
    TestCls(TestCls &&other)
    {
        std::cout << "[TestCls] move constructor" << std::endl;
    }
    TestCls &operator =(const TestCls &other)
    {
        std::cout << "[TestCls] copy assignment" << std::endl;
        return *this;
    }
    TestCls &operator =(TestCls &&other)
    {
        std::cout << "[TestCls] move assignment" << std::endl;
        return *this;
    }
};
void test2()
{
    TestCls a, b;

    std::cout << std::endl << "unique_future test begin" << std::endl;
    boost::unique_future<TestCls> fu1 = boost::async([]{ return TestCls(); });
    fu1.wait();
    std::cout << "first assignment" << std::endl;
    a = fu1.get();
    std::cout << "second assignment" << std::endl;
    b = fu1.get();
    std::cout << "unique_future test end" << std::endl;

    std::cout << std::endl << "shared_future test begin" << std::endl;
    boost::shared_future<TestCls> fu2 = boost::async([]{ return TestCls(); });
    fu2.wait();
    std::cout << "first assignment" << std::endl;
    a = fu2.get();
    std::cout << "second assignment" << std::endl;
    b = fu2.get();
    std::cout << "shared_future test end" << std::endl;

    std::cin.get();
}

输出是:

[TestCls] default constructor
[TestCls] default constructor

unique_future test begin
[TestCls] default constructor
[TestCls] move constructor
first assignment
[TestCls] move constructor
[TestCls] move assignment
second assignment
[TestCls] move constructor
[TestCls] move assignment
unique_future test end

shared_future test begin
[TestCls] default constructor
[TestCls] move constructor
first assignment
[TestCls] copy assignment
second assignment
[TestCls] copy assignment
shared_future test end

虽然的boost :: unique_future 做动,而不是复制,允许调用 GET 很多时候..这怎么可能?

Although boost::unique_future do "move", not "copy", it is allowed to call get many times.. How is it possible?

(我的提升版本是1.55.0,我的编译器是VC ++ 2013)

(My boost version is 1.55.0, and my compiler is VC++ 2013)

如果我的#define BOOST_THREAD_VERSION 4 ,异常发生在获取的第二个电话()获取的多个呼叫()是不确定的行为,直到3版本?或者,它是允许的,直到3版本?

If I do #define BOOST_THREAD_VERSION 4, an exception occurs at the second call of get(). multiple call of get() is undefined behavior until version 3? Or it's allowed until version 3?

推荐答案

从<一个href=\"http://www.boost.org/doc/libs/1_55_0/doc/html/thread/build.html#thread.build.configuration.future\"相对=nofollow>的文档很显然,至少有3宏都打在你使用什么显著的作用

From the documentation it's clear that there are at least 3 macro that are playing a significant role in what you are using

BOOST_THREAD_VERSION

这台库的版本,即使有4个和3之间重大更改,你似乎没有有问题这一点。

which sets the version of the library, even if there are breaking changes between 4 and 3, you don't seem to have a problem with that.

第二个宏是 BOOST_THREAD_PROVIDES_FUTURE ,这个宏是一个开关,没有任何附加的价值,如果定义它使标准期货,而不是unique_futures,你在呼唤什么 unique_future 仅仅是由该宏在编译时定义的内容的占位符。

second macro is BOOST_THREAD_PROVIDES_FUTURE, this macro is a switch, no value attached, if defined it enables the "standard" futures, not the unique_futures, what you are calling unique_future is just a placeholder for something that is defined by this macro at compile time.

从文件升压/线程/ future.hpp

#if defined BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_FUTURE future
#else
#define BOOST_THREAD_FUTURE unique_future
#endif

文件中的升压/线程/细节/ config.hpp 你也有 BOOST_THREAD_DONT_PROVIDE_FUTURE 这是另一个交换机默认操作

in the file boost/thread/detail/config.hpp you also have BOOST_THREAD_DONT_PROVIDE_FUTURE which is another switch for default actions

// PROVIDE_FUTURE
#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE \
 && ! defined BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE
#endif

请注意否定,这意味着如果你定义 BOOST_THREAD_DONT_PROVIDE_FUTURE 你应该得到真正的 unique_future 的库文件。

note the negation !, which means that if you define BOOST_THREAD_DONT_PROVIDE_FUTURE you should get "real" unique_future as documented by the library.

您基本上得到默认行为,并正在使用的库的版本4不管那么多了这一事实。

You are basically getting the default behaviour and the fact that you are using the version 4 of the library doesn't matter that much.

一个侧面说明关于C ++ 11及以后:

A side note about C++11 and beyond:

std::async([]{ return 42; });

这是在C ++ 11不好的做法,它在C ++ 14未定义行为,你应该总是指定启动策略的异步

this is bad practice in C++11 and it's undefined behaviour in C++14, you should always specify a launch policy for your async.

这篇关于为什么我可以调用的boost :: unique_future ::获得了很多次,不同的std ::未来?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆