在一个线程中完成的操作对另一个线程可见,无需显式同步

Operations done in one thread visible to another without explicit synchronization

我的问题是关于线程同步的。请看下面的代码:

std::vector<int> v_int;

for (size_t i = 0; i < 5; ++i) {
    v_int.emplace_back(i);
}

auto f_async = std::async(std::launch::async,
    [](auto v_int) mutable {
        for (auto& el : v_int.get()) {
            el += 10;
        }
    }, std::ref(v_int));

//more instructions...

f_async.get();

我的问题 是 std::async 产生的新线程如何“看到”(主)线程对向量所做的修改,假设没有acquire-release (mutex, atomic bool, atomic flag...) 来保护向量?

是否存在隐式顺序一致性,因为新线程在完全写入向量后“发生”?

一个典型的生产者/消费者看起来像这样:

std::vector<int> v_int_global;
std::atomic<bool> data_ready{ false };

void producer_int() {
    for (size_t i = 0; i < 5; ++i) {
        v_int_global.emplace_back(i);
    }
    data_ready.store(true, std::memory_order_release);
}

void transformer_int() {
    while (!data_ready.load(std::memory_order_acquire));
    for (auto& el : v_int_global) {
        el += 10;
    }
}

int main() {
    std::thread t1 (producer_int);
    std::thread t2 (transformer_int);

    t1.join();
    t2.join();
}

谢谢。

std::async 指定为与​​参数 ([futures.async]/p5) 的调用同步:

Synchronization: Regardless of the provided policy argument,

(5.1) the invocation of async synchronizes with the invocation of f. [ Note: This statement applies even when the corresponding future object is moved to another thread.  — end note ] ; and

(5.2) the completion of the function f is sequenced before ([intro.multithread]) the shared state is made ready. [ Note: f might not be called at all, so its completion might never happen.  — end note ]

术语synchronizes-with表示至少有一个“acquire-release”事件将要发生。因此,无论何时执行,都保证在调用 std::async 之前完成的任何工作对 lambda 可见。

类似地,future::get() 与将结果存储在共享状态 ([futures.state]/p9) 的调用同步:

Calls to functions that successfully set the stored result of a shared state synchronize with calls to functions successfully detecting the ready state resulting from that setting. The storage of the result (whether normal or exceptional) into the shared state synchronizes with the successful return from a call to a waiting function on the shared state.