程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 陳詞濫調C++的單例形式與線程平安單例形式(懶漢/餓漢)

陳詞濫調C++的單例形式與線程平安單例形式(懶漢/餓漢)

編輯:關於C++

陳詞濫調C++的單例形式與線程平安單例形式(懶漢/餓漢)。本站提示廣大學習愛好者:(陳詞濫調C++的單例形式與線程平安單例形式(懶漢/餓漢))文章只能為提供參考,不一定能成為您想要的結果。以下是陳詞濫調C++的單例形式與線程平安單例形式(懶漢/餓漢)正文


1 教科書裡的單例形式

我們都很清楚一個復雜的單例形式該怎樣去完成:結構函數聲明為private或protect避免被內部函數實例化,外部保管一個private static的類指針保管獨一的實例,實例的舉措由一個public的類辦法代勞,該辦法也前往單例類獨一的實例。

上代碼: 

class singleton
{
protected:
  singleton(){}
private:
  static singleton* p;
public:
  static singleton* instance();
};
singleton* singleton::p = NULL;
singleton* singleton::instance()
{
  if (p == NULL)
    p = new singleton();
  return p;
}

這是一個很棒的完成,復雜易懂。但這是一個完滿的完成嗎?不!該辦法是線程不平安的,思索兩個線程同時初次調用instance辦法且同時檢測到p是NULL值,則兩個線程會同時結構一個實例給p,這是嚴重的錯誤!同時,這也不是單例的獨一完成!

2 懶漢與餓漢

單例大約有兩種完成辦法:懶漢與餓漢。

懶漢:故名思義,不到萬不得已就不會去實例化類,也就是說在第一次用到類實例的時分才會去實例化,所以上邊的經典辦法被歸為懶漢完成;

餓漢:餓了一定要狼吞虎咽。所以在單例類定義的時分就停止實例化。

特點與選擇:

由於要停止線程同步,所以在訪問量比擬大,或許能夠訪問的線程比擬多時,采用餓漢完成,可以完成更好的功能。這是以空間換時間。

在訪問量較小時,采用懶漢完成。這是以時間換空間。

3 線程平安的懶漢完成

線程不平安,怎樣辦呢?最直觀的辦法:加鎖。

辦法1:加鎖的經典懶漢完成:

class singleton
{
protected:
  singleton()
  {
    pthread_mutex_init(&mutex);
  }
private:
  static singleton* p;
public:
  static pthread_mutex_t mutex;
  static singleton* initance();
};

pthread_mutex_t singleton::mutex;
singleton* singleton::p = NULL;
singleton* singleton::initance()
{
  if (p == NULL)
  {
    pthread_mutex_lock(&mutex);
    if (p == NULL)
      p = new singleton();
    pthread_mutex_unlock(&mutex);
  }
  return p;
}

辦法2:外部靜態變量的懶漢完成

此辦法也很容易完成,在instance函數裡定義一個靜態的實例,也可以保證擁有獨一實例,在前往時只需求前往其指針就可以了。引薦這種完成辦法,真得十分復雜。

class singleton
{
protected:
  singleton()
  {
    pthread_mutex_init(&mutex);
  }
public:
  static pthread_mutex_t mutex;
  static singleton* initance();
  int a;
};

pthread_mutex_t singleton::mutex;
singleton* singleton::initance()
{
  pthread_mutex_lock(&mutex);
  static singleton obj;
  pthread_mutex_unlock(&mutex);
  return &obj;
}

4 餓漢完成

為什麼我不講“線程平安的餓漢完成”?由於餓漢完成原本就是線程平安的,不必加鎖。為啥?自己想!

class singleton
{
protected:
  singleton()
  {}
private:
  static singleton* p;
public:
  static singleton* initance();
};
singleton* singleton::p = new singleton;
singleton* singleton::initance()
{
  return p;
}

是不是特別復雜呢?

以空間換時間,你說復雜不復雜?

面試的時分,線程平安的單例形式怎樣寫?一定怎樣復雜怎樣寫呀!餓漢形式反而最懶[正派臉]! 

以上就是為大家帶來的陳詞濫調C++的單例形式與線程平安單例形式(懶漢/餓漢)全部內容了,希望大家多多支持~

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved