在thread :: join上是否存在具有与同步关系的隐式内存屏障? [英] Is there an implicit memory barrier with synchronized-with relationship on thread::join?

查看:119
本文介绍了在thread :: join上是否存在具有与同步关系的隐式内存屏障?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个正在工作的代码,它启动多个执行某些操作的线程,如果其中任何一个失败,则将共享变量设置为 false .

I have a code at work that starts multiple threads that doing some operations and if any of them fail they set the shared variable to false.

然后,主线程加入所有工作线程.对此的模拟大致如下(我注释掉了可能的修复程序,我不知道是否需要此修复程序):

Then main thread joins all the worker threads. Simulation of this looks roughly like this (I commented out the possible fix which I don't know if it's needed):

#include <thread>
#include <atomic>
#include <vector>
#include <iostream>
#include <cassert>

using namespace std;

//atomic_bool success = true;
bool success = true;

int main()
{
    vector<thread> v;
    for (int i = 0; i < 10; ++i)
    {
        v.emplace_back([=]
        {
            if (i == 5 || i == 6)
            {
                //success.store(false, memory_order_release);
                success = false;
            }
        });
    }
    for (auto& t : v)
        t.join();

    //assert(success.load(memory_order_acquire) == false);
    assert(success == false);

    cout << "Finished" << endl;
    cin.get();
    return 0;
}

即使其中一个工作程序将成功变量设置为 false ,主线程是否也有可能将成功变量读取为 true ?

Is there a possibility that main thread will read the success variable as true even though one of the workers set it to false?

我发现 thread :: join()是一个完整的内存屏障(

I found that thread::join() is a full memory barrier (source) but does that imply synchronized-with relationship with the following read of success variable from the main thread, so that we're guaranteed to get newest value?

在这种情况下(在注释的代码中)发布的修复程序是否必要(如果此错误,则可能是另一种修复程序)?

Is the fix I posted (in the commented code) necessary in this case (or maybe another fix if this one is wrong)?

是否有可能对成功变量的读取进行优化(因为它不是易变的),并且无论应该存在隐式内存障碍如何,我们都将获得旧值在 thread :: join 吗?

Is there a possibility that read of success variable will be optimized away (since it's not volatile) and we will get old value regardless of suppossed to exist implicit memory barrier on thread::join?

假定该代码可在多种体系结构上运行(无法记住所有体系结构,我面前没有makefile),但至少有x86,amd64,itanium,arm7.

谢谢您的帮助.

我已经修改了该示例,因为在实际情况下,一个线程可以尝试写入成功变量.

I've modified the example, because in real situation more then one thread can try to write to success variable.

推荐答案

上面的代码表示数据竞争,使用join不能更改该事实.如果只有一个线程写入该变量,那就没问题了.但是,您有两个线程在写它们,它们之间的同步是 no .那是一场数据竞赛.

The code above represents a data race, and the use of join cannot change that fact. If only one thread wrote to the variable, it would be fine. But you have two threads writing to it, with no synchronization between them. That's a data race.

join仅表示该线程操作的所有副作用都已完成,现在对您可见."那样不会在该线程和除您自己的线程之外的任何其他线程之间创建顺序或同步.

join simply means "all side effects of that thread's operation have completed and are now visible to you." That does not create ordering or synchronization between that thread and any thread other than your own.

如果您使用的是atomic_bool,则它不是UB.这将保证是错误的.但是由于存在数据争用,您将获得纯UB.可能是真,假或鼻恶魔.

If you used an atomic_bool, then it wouldn't be UB; it would be guaranteed to be false. But because there is a data race, you get pure UB. It might be true, false, or nasal demons.

这篇关于在thread :: join上是否存在具有与同步关系的隐式内存屏障?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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