3

通过打包的任务创建一个线程并std::vector返回一个。

#include <iostream>
#include <future>
#include <thread>
#include <vector>

std::vector<int> func(int &arg)
{
    std::vector<int> v = {1,2,3,4};

    arg = 10;

    return v;
}

int main()
{
    std::packaged_task<std::vector<int>(int &)> pt{func};
    auto fut = pt.get_future();

    int arg = 0;
    std::thread thr{std::move(pt), std::ref(arg)};

    auto vec = fut.get();

    std::cout << arg << std::endl;  // data race here ?

    thr.join();
}

std::future保证向量与线程同步(main之前join),但我不确定打包任务参数的状态(通过引用传递)。

所以问题是是否存在数据竞赛arg

4

1 回答 1

3
int arg=0;

发生在我们启动线程之前thr,因为它是在它之前排序的

arg = 10;

由于调用,这发生在之前被初始化: vec.get()

auto vec=fut.get();

这是先排序的

std::cout << arg << std::endl;

所以我在这里没有看到数据竞争。

虽然不是权威,但cpp 参考声称:

Promise 是 Promise-Future 通信通道的“推送”端:在共享状态中存储值的操作与(如 std::memory_order 中定义的)同步,从等待共享的任何函数的成功返回状态(例如 std::future::get)。

也有类似的词std::async。我相信类似的保证适用于packaged_task;毕竟,它旨在用作一种原语来帮助实现您自己的std::async类似行为。

于 2018-12-10T19:28:12.907 回答