In some scenarios , We need the code to be executed only once , For example, the initialization of singleton classes , Considering multithreading security , Lock control is required .C++11 Provided in call_once Can be very good to meet this demand , It's very simple to use .

Header file #include<mutex>

        template <class Fn, class... Args>

        void call_once (once_flag& flag, Fn&& fn, Args&&...args);

       
The first parameter is the first one std::once_flag Object of (once_flag It is not allowed to modify , Its copy constructor and operator= Functions are declared as delete), The second parameter calls the entity , Code that requires execution only once , The following variable parameter is its parameter list .

        call_once Guarantee function fn Only once , If multiple threads execute the function at the same time fn call , There is only one active thread (active
call) Can execute functions , Other threads will be in the ”passive
execution”( Passive execution state )—— No direct return , Until the active thread pair fn Return after the end of the call . For all calling functions fn Concurrent threads for , Data visibility is synchronized ( coincident ).

        If the active thread is executing fn Throw an exception , From the ”passive
execution” Select one of the threads in the state to become the active thread to continue execution fn, And so on . Once the active thread returns , All ”passive
execution” The state of the thread is also returned , Does not become an active thread .( actually once_flag Equivalent to a lock , The thread that uses it will wait on it , Only one thread is allowed to execute . If the thread throws an exception , Then select one of the waiting threads , Repeat the above process ).

        static std::once_flag oc;  // be used for call_once Local static variables of

        Singleton* Singleton::m_instance;

        Singleton* Singleton::getInstance() {

            std::call_once(oc, [&] () { m_instance = newSingleton(); });

            return m_instance;

        }

         Another thing to note is that once_flag Life cycle of , It has to be longer than the thread that uses it . Therefore, it is better to define it as a global variable .

Technology