[Concurrent concurrency] _ [thread synchronization] _ [Analysis of the single-instance mode using C/C ++]

Source: Internet
Author: User

[Concurrent concurrency] _ [thread synchronization] _ [Analysis of the single-instance mode using C/C ++]

 

Scenario:

1. in many cases, we need to implement the singleton mode of a class, such as XXManager, so we provide a GetInstance () function. java can use double locks for processing. c/C ++ is similar.

2. A required condition for providing GetInstance () must be thread-safe; otherwise, multiple instances may be created. a simpler approach is to (Main thread) during program initialization)

A CreateInstance () function is called to create the instance. However, if there are more single-instance objects, CreateInstance calls will increase. If you forget to call the CreateInstance function, it will crash.

3. Here we implement the method of creating the singleton mode in C/C ++. One is created using the pthread library, and the other is created using the win32 api.

 

4. Objc can use dispatch_once to implement the singleton mode.

 

+(DhTaskManager*)getInstance{    static DhTaskManager *manager = nil;    static dispatch_once_t predicate;    dispatch_once(&predicate, ^{        manager = [DhTaskManager new];    });    return manager;}

 


 

 

Test. cpp

 

# Include
 
  
# Include
  
   
# Include pthread. h # include
   
    
# Include static int THREADCOUNT = 100; class CSLock {public: CSLock () {InitializeCriticalSection (& cs _); std: cout <init lock! <Std: endl ;}~ CSLock () {DeleteCriticalSection (& cs _);} operator PCRITICAL_SECTION () throw () {return & cs _ ;}private: CRITICAL_SECTION cs _ ;}; // scenario 1: create a singleton object. class UiDeviceManager {public: static void Destroy () {delete singleton _ ;}// 1. use pthread_once to implement the singleton mode. static UiDeviceManager * GetInstance () {pthread_once (& random_is_initialized, init_instance); return singleton _ ;}// 1. use Windows atomic locks to implement Singleton mode, without the need for the pthread library static UiDeviceManage R * GetInstance2 () {static LONG done = 0; if (! InterlockedExchangeAdd (& done, 0) {EnterCriticalSection (cs_lock _); if (! Done) {init_instance (); done = 1;} invoke (cs_lock _);} return singleton _;} private: static pthread_once_t random_is_initialized; static CSLock cs_lock _; static void init_instance () {// test, Sleep 3 seconds, verify that this function is executed only once. // check whether there are any threads entering this. // test Sleep (3000); std: cout <Sleep End <std: endl; static LONG locki _; // 1. this variable is only used for testing. interlockedExchangeAdd (& locki _, 1); assert (locki _ = 1); // you only need newsingleton _ = new UiDeviceManager ();} UiDeviceManager () {} static UiDeviceManager * singleton _;}; CSLock UiDeviceManager: cs_lock _; Define UiDeviceManager: Consumer = PTHREAD_ONCE_INIT; UiDeviceManager * UiDeviceManager: singleton _ = NULL; static pthread_barrier_t barrier = NULL; void * ThreadFunc (void * data) {for (int I = 0; I <10000; ++ I) {// UiDeviceManager * udm = UiDeviceManager :: getInstance (); UiDeviceManager * udm = UiDeviceManager: GetInstance2 ();} pthread_barrier_wait (& barrier); std: cout <ThreadFunc Finish <std: endl; return NULL;} void TestPthreadOnce () {pthread_barrier_init (& barrier, NULL, THREADCOUNT + 1); for (int I = 0; I <THREADCOUNT; ++ I) {pthread_t; pthread_create (& t, NULL, ThreadFunc, NULL); pthread_detach (t);} std: cout <TestPthreadOnce Begin <std: endl; pthread_barrier_wait (& barrier ); std: cout <TestPthreadOnce Finish <std: endl; pthread_barrier_destroy (& barrier); UiDeviceManager: Destroy ();} int main (int argc, char const * argv []) {TestPthreadOnce (); return 0 ;}
   
  
 


 

Output:

 

init lock!TestPthreadOnce BeginSleep EndThreadFunc FinishThreadFunc FinishThreadFunc FinishTestPthreadOnce FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc FinishThreadFunc Finish

Refer:

 

Http://www.douban.com/note/269039110/ this is actually flawed!

Pthread_once function source code:

 

intpthread_once (pthread_once_t * once_control, void (*init_routine) (void)){  if (once_control == NULL || init_routine == NULL)    {      return EINVAL;    }    if (!InterlockedExchangeAdd((LPLONG)&once_control->done, 0)) /* MBR fence */    {      ptw32_mcs_local_node_t node;      ptw32_mcs_lock_acquire((ptw32_mcs_lock_t *)&once_control->lock, &node);      if (!once_control->done){#ifdef _MSC_VER#pragma inline_depth(0)#endif  pthread_cleanup_push(ptw32_once_on_init_cancel, (void *)&node);  (*init_routine)();  pthread_cleanup_pop(0);#ifdef _MSC_VER#pragma inline_depth()#endif  once_control->done = PTW32_TRUE;}ptw32_mcs_lock_release(&node);    }  return 0;}/* pthread_once */

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.