原子布尔标志能否确保同步?

时间:2022-09-01 21:02:01

I was asking myself if an atomic bool ready flag could ensure that a data is syncronised between thread (I have already read this Synchronization Mechanism For "data ready" Flag? ) but no comment answer to my question.

我问自己一个原子bool就绪标志是否可以确保数据在线程之间同步(我已经读过这个同步机制用于“数据就绪”标志?)但我的问题没有评论答案。

for exemple see this code :

例如,请参阅此代码:

#include<atomic>
#include<thread>

class BIG_DATA {
public:
    BIG_DATA(){ std::this_thread::sleep_for(std::chrono::seconds(1)); }//some big data to init ......
};
void init_BIG_DATA(BIG_DATA* & location, std::atomic<bool>& flag ) {
    if (flag.load())throw("error : data already loaded");
    location = new BIG_DATA(); //heavy operation
    flag.store(true);
}
class data {
public:
    data() {
        ready.store(false);
        std::thread t = std::thread(init_BIG_DATA,std::ref(_data),std::ref(ready));
        t.detach();
    }
    BIG_DATA* get_data() {
        if (ready.load()) return _data;
        else return nullptr;
    }
private:
    BIG_DATA* _data = nullptr;
    std::atomic<bool> ready;
};

in this code if i have a main like this :

在这段代码中如果我有这样的主要:

data d;
while (d.get_data() == nullptr) ; // wait for Big data to be constructed in an other thread
BIG_DATA* BD = d.get_data();
// do somethin with big data

Do I am ensured that the thing I do with the BIG_DATA* (BD) are correct and that the object is sycronised between the creator and worker thread ? Is this code thread safe ?

我是否确保我使用BIG_DATA *(BD)做的事情是正确的,并且该对象是在创建者和工作者线程之间进行了同步?这段代码线程安全吗?

1 个解决方案

#1


0  

There is a design problem here. Looking at the code, I see two requirements:

这里有一个设计问题。看一下代码,我看到两个要求:

  1. BIG_DATA must be initialised and that will take some time.

    必须初始化BIG_DATA,这需要一些时间。

  2. The main thread must block while BIG_DATA is being constructed.

    在构造BIG_DATA时,主线程必须阻塞。

This begs the question, since BIG_DATA's construction takes place in one thread only, why not simply create it in the main thread?

这引出了一个问题,因为BIG_DATA的构造仅在一个线程中进行,为什么不在主线程中简单地创建呢?

In this case all problems to do with temporal synchronisation and cross-thread propagation of variable changes simply vanish.

在这种情况下,与时间同步和变量的跨线程传播有关的所有问题都会消失。

However, that aside, yes this code is thread-safe, because the default memory order of an atomic is 'full sequential consistency'. This means that the write to BIG_DATA's pointer will 'happen before' the write to the atomic protecting it, and that ordering will be propagated across threads.

但是,除此之外,是的,这段代码是线程安全的,因为原子的默认内存顺序是“完全顺序一致性”。这意味着对BIG_DATA指针的写入将“发生在”保护它的原子写入之前,并且该顺序将在线程之间传播。

A store operation with this memory order performs the release operation: no memory accesses in the current thread can be reordered after this store. This ensures that all writes in the current thread are visible in other threads that acquire the same atomic variable and writes that carry a dependency into the atomic variable become visible in other threads that consume the same atomic.

具有此内存顺序的存储操作将执行释放操作:在此存储之后,不能对当前线程中的内存访问进行重新排序。这确保了当前线程中的所有写入在获取相同原子变量的其他线程中可见,并且带有依赖关系到原子变量的写入在消耗相同原子的其他线程中变得可见。

#1


0  

There is a design problem here. Looking at the code, I see two requirements:

这里有一个设计问题。看一下代码,我看到两个要求:

  1. BIG_DATA must be initialised and that will take some time.

    必须初始化BIG_DATA,这需要一些时间。

  2. The main thread must block while BIG_DATA is being constructed.

    在构造BIG_DATA时,主线程必须阻塞。

This begs the question, since BIG_DATA's construction takes place in one thread only, why not simply create it in the main thread?

这引出了一个问题,因为BIG_DATA的构造仅在一个线程中进行,为什么不在主线程中简单地创建呢?

In this case all problems to do with temporal synchronisation and cross-thread propagation of variable changes simply vanish.

在这种情况下,与时间同步和变量的跨线程传播有关的所有问题都会消失。

However, that aside, yes this code is thread-safe, because the default memory order of an atomic is 'full sequential consistency'. This means that the write to BIG_DATA's pointer will 'happen before' the write to the atomic protecting it, and that ordering will be propagated across threads.

但是,除此之外,是的,这段代码是线程安全的,因为原子的默认内存顺序是“完全顺序一致性”。这意味着对BIG_DATA指针的写入将“发生在”保护它的原子写入之前,并且该顺序将在线程之间传播。

A store operation with this memory order performs the release operation: no memory accesses in the current thread can be reordered after this store. This ensures that all writes in the current thread are visible in other threads that acquire the same atomic variable and writes that carry a dependency into the atomic variable become visible in other threads that consume the same atomic.

具有此内存顺序的存储操作将执行释放操作:在此存储之后,不能对当前线程中的内存访问进行重新排序。这确保了当前线程中的所有写入在获取相同原子变量的其他线程中可见,并且带有依赖关系到原子变量的写入在消耗相同原子的其他线程中变得可见。