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,
The 11th Blue Bridge Cup python The real topic of the University Group National Games JavaSwing To achieve a simple Lianliankan games 【Spring Source code analysis 】42-@Conditional Detailed explanation element-ui Step on pit record 2019PHP Interview questions ( Continuously updated )PHPJava Misunderstanding —— Method overloading is a manifestation of polymorphism ? First issue 500 100 million , Set up a new Department , What is Tencent going to do ? Google chrome The browser can't open the web page , But what if other browsers can open it ? Regression of dependent variable order categories (R language )【Golang Basic series 10 】Go language On conditional sentences if