boost::call_once Application and Implementation

 

Here is a typical application call_once An example of implementing an initialization :

 1 #include <boost/thread/thread.hpp>
 2 #include <boost/thread/once.hpp>
 3 #include <iostream>
 4 
 5 int i = 0;
 6 int j = 0;
 7 boost::once_flag flag = BOOST_ONCE_INIT;
 8 
 9 void init()
10 {
11     ++i;
12 }
13 
14 void thread()
15 {
16     boost::call_once(&init, flag);
17     ++j;
18 }
19 
20 int main(int argc, char* argv[])
21 {
22     boost::thread thrd1(&thread);
23     boost::thread thrd2(&thread);
24     thrd1.join();
25     thrd2.join();
26 
27     std::cout << i << std::endl;
28     std::cout << j << std::endl;
29 
30     return 0;
31 }
The results show that , global variable i Was executed only once ++ operation , And variables j Is executed in both threads ++ operation .

 

principle :

    Using incoming flag Address and current process id Construct a string for a variable , And use this string to construct a named mutex,
Make this mutex In the same process , Relative identical flag only . For the first time mutex The thread of ownership executes the incoming function object , And will flag Change to a specific value ,
Other thread judgment flag Is it modified to this specific value , If it is modified, the function will not be called and it will be skipped directly . Using double judgment mechanism to reduce the call waitforsingleobject Times of , increase of efficiency

Key source code :

 

void call_once(once_flag& flag,Function f)
    {
        // Try for a quick win: if the procedure has already been called
        // just skip through:
        long const function_complete_flag_value=0xc15730e2; //
First time finish call Later flag The value is modified to this value

       
if(::boost::detail::interlocked_read_acquire(&flag)!=function_complete_flag_value)//
First judgment , Can be reduced waitforsingleobject frequency
        {
            void* const
mutex_handle(::boost::detail::create_once_mutex(&flag));// Create process unique metux
            BOOST_ASSERT(mutex_handle);
            detail::win32::handle_manager const closer(mutex_handle); //handle
guard, Leave scope automatically closehandle
            detail::win32_mutex_scoped_lock const lock(mutex_handle); //mutex
guard, In the constructor waitforsingleobject( Incoming mutex handle), Leave scope automatically releaseMutex
       
            if(flag!=function_complete_flag_value)//
Second judgment ,waitforsingleobject Then judge again call Has it been called
            {
                f();
               
BOOST_INTERLOCKED_EXCHANGE(&flag,function_complete_flag_value);// Atomic operation , to flag assignment
            }
        }
    }

 

 

Technology
©2019-2020 Toolsou All rights reserved,
Python Garbage collection and memory leak hive Summary of processing methods for a large number of small files The difference between memory overflow and memory leak , Causes and Solutions Create data mysql Library process You don't know ——HarmonyOS stay Vue Use in Web WorkerSparkSQL Achieve partition overlay write msf Generate Trojan horse attack android mobile phone Linux Page replacement algorithm C Language implementation Django Personal blog building tutorial --- Time classified archiving