std::call_once vs std::mutex for thread-safe initialization

后端 未结 3 1085
南笙
南笙 2021-02-05 10:16

I\'m a bit confused about the purpose of std::call_once. To be clear, I understand exactly what std::call_once does, and how to use it. It\'

3条回答
  •  被撕碎了的回忆
    2021-02-05 11:01

    One thing that call_once does for you is handle exceptions. That is, if the first thread into it throws an exception inside of the functor (and propagates it out), call_once will not consider the call_once satisfied. A subsequent invocation is allowed to enter the functor again in an effort to complete it without an exception.

    In your example, the exceptional case is also handled properly. However it is easy to imagine a more complicated functor where the exceptional case would not be properly handled.

    All this being said, I note that call_once is redundant with function-local-statics. E.g.:

    CSingleton& CSingleton::GetInstance()
    {
        static std::unique_ptr m_instance(new CSingleton);
        return *m_instance;
    }
    

    Or more simply:

    CSingleton& CSingleton::GetInstance()
    {
        static CSingleton m_instance;
        return m_instance;
    }
    

    The above is equivalent to your example with call_once, and imho, simpler. Oh, except the order of destruction is very subtly different between this and your example. In both cases m_instance is destroyed in reverse order of construction. But the order of construction is different. In your m_instance is constructed relative to other objects with file-local scope in the same translation unit. Using function-local-statics, m_instance is constructed the first time GetInstance is executed.

    That difference may or may not be important to your application. Generally I prefer the function-local-static solution as it is "lazy". I.e. if the application never calls GetInstance() then m_instance is never constructed. And there is no period during application launch when a lot of statics are trying to be constructed at once. You pay for the construction only when actually used.

提交回复
热议问题