Изменить значения, захваченные ссылкой в ​​лямбда-выражении std :: future - PullRequest
2 голосов
/ 26 января 2020

Может кто-нибудь объяснить мне, почему изменение значений, захваченных по ссылке в лямбда-выражении std :: future, не дает ожидаемого результата? Смотрите код:

const int runs{ 1000 };
for (int run = 0; run < runs; ++run)
{
    const int num{ 4 };
    std::vector<bool> res(num, false);
    std::vector<std::future<void>> futs(num);
    for (int i = 0; i < num; ++i)
    {
        futs[i] = std::async(std::launch::async, [&res, i]
        {
            res[i] = true;
        });
    }
    for (auto& fut : futs) fut.wait();
    for (auto v : res) // I expect all values of res to be set to true.
    {
        if (!v) std::cerr << "Bad!!!\n"; // But this happens!
    }
}

1 Ответ

0 голосов
/ 26 января 2020

У вас есть гонки данных, которые ведут к неопределенному поведению. Различные элементы vector<bool> не должны изменяться одновременно разными потоками.

Вы можете прочитать об этом здесь

Не гарантирует, что различные элементы в один и тот же контейнер может быть изменен одновременно различными потоками.

или здесь

Несмотря на [res.on.data.races], реализации необходимы чтобы избежать скачек данных, когда содержимое содержащегося объекта в разных элементах в одном и том же контейнере, за исключением вектора, изменяется одновременно.

...