Are volatile reads and writes atomic on Windows+VisualC?

后端 未结 5 2094
逝去的感伤
逝去的感伤 2020-12-14 04:49

There are a couple of questions on this site asking whether using a volatile variable for atomic / multithreaded access is possible: See here, here, or here for

5条回答
  •  北荒
    北荒 (楼主)
    2020-12-14 05:23

    The point is probably to allow stuff like

    singleton& get_instance()
    {
        static volatile singleton* instance;
        static mutex instance_mutex;
    
        if (!instance)
        {
            raii_lock lock(instance_mutex);
    
            if (!instance) instance = new singleton;
        }
    
        return *instance;
    }
    

    which would break if instance was written to before initialization was complete. With MSVC semantics, you are guaranteed that as soon as you see instance != 0, the object has finished being initialized (which is not the case without proper barrier semantics, even with traditional volatile semantics).

    This double-checked lock (anti-)pattern is quite common actually, and broken if you don't provide barrier semantics. However, if there are guarantees that accesses to volatile variables are acquire + release barriers, then it works.

    Don't rely on such custom semantics of volatile though. I suspect this has been introduced not to break existing codebases. In any way, don't write locks according to MSDN example. It probably doesn't work (I doubt you can write a lock using just a barrier: you need atomic operations -- CAS, TAS, etc -- for that).

    The only portable way to write the double-checked lock pattern is to use C++0x, which provides a suitable memory model, and explicit barriers.

提交回复
热议问题