Есть ли гонка данных на аргументах упакованных задач? - PullRequest
0 голосов
/ 10 декабря 2018

Поток создается с помощью упакованной задачи, и возвращается 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?

1 Ответ

0 голосов
/ 10 декабря 2018
int arg=0;

это происходит до мы запускаем поток thr, поскольку он упорядочен до it.

arg = 10;

это происходит-до vec инициализируется из-за вызова .get():

auto vec=fut.get();

, который упорядочен до-до

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

поэтому я не вижу здесь никакой гонки данных.

Хотя это и не авторитетно, cpp reference претензий:

Обещание - это "толчок" конца обещания-будущегоканал связи: операция, которая хранит значение в общем состоянии, синхронизирует с (как определено в std :: memory_order) успешный возврат из любой функции, которая ожидает в общем состоянии (например, std :: future :: get).

есть похожие слова и для std::async.Я полагаю, что аналогичная гарантия действует для packaged_task;он предназначен для использования в качестве примитива, чтобы помочь реализовать ваше собственное std::async подобное поведение в конце концов.

...