0

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.

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 ?

Community
  • 1
  • 1

1 Answers1

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.

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

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

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.

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.

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • so the thing is I want to use it to load an image from disk or internet or somwere else so I want is : -image is used as soon as it is ready but as long as it isn't i don't display it(as long as nullptr is thrown) but display the other element . Is my aproach good ? – Hervé Hugonnet Jun 25 '16 at 16:18
  • The normal way to approach this is that the thread loading I the image would post a call to a closure to a message queue running in the main thread. This call would notify the main thread that the image is ready. – Richard Hodges Jun 25 '16 at 16:20