void undefined_behaviour_with_double_checked_locking()
{
    if(!resource_ptr)                                    #1
    {
        std::lock_guard<std::mutex> lk(resource_mutex);  #2
        if(!resource_ptr)                                #3
        {
           resource_ptr.reset(new some_resource);        #4
        }
    }
    resource_ptr->do_something();                        #5
}
if a thread sees the pointer written by another thread, it might not see the newly-created instance of some_resource, resulting in the call to do_something() operating on incorrect values. This is an example of the type of race condition defined as a data race by the C++ Standard, and thus specified as undefined behaviour.
Question> I have seen the above explanation for why the code has the double checked locking problem that causes the race condition. However, I still have difficulties to understand what the problem is. Maybe a concrete two-threads step-by-step workflow can help me really understand the race problem for the above the code.
One of the solution mentioned by the book is as follows:
std::shared_ptr<some_resource> resource_ptr;
std::once_flag resource_flag;
void init_resource()
{
    resource_ptr.reset(new some_resource);
}
void foo()
{
    std::call_once(resource_flag,init_resource); #1
    resource_ptr->do_something();
}
#1 This initialization is called exactly once
Any comment is welcome -Thank you
 
     
     
    