C ++同時実行性とマルチスレッドの研究ノート - シングルトンデザインパターン、共有データ解析

  • デザインパターン
  • 共有データ分析
  • なcall_once

 


 

デザインパターン

開発プログラムは、いくつかの特別な言葉遣いで、これらの従来の書き込みと書き込みは同じではありませんが、プログラム柔軟性、それらを維持しやすい、他の人がコードは非常に苦痛になるだろう読んで取り上げました。コードによって書かれたデザインパターンの非常にあいまいな概念、国内の05〜10年である「ヘッドファースト」があるとき、書かれた手順は、デザインパターンになります。

プロジェクト開発の経験+デザインモードでのモジュールの開発経験=

まず、開発ニーズ、その後、大規模なプロジェクトに非常に多くの小さなモジュール、デザインパターンのその後の進化を分割します。中国へのデザインパターンの広がりが来るとき、多くのプログラマは、セットにコードデザインモードにコードを記述するので、非常に小さなプログラムは複雑で不明瞭なソースコードは、もともと小さなスプリットに大きなものをモデル化するために設計されてしまうこと物事、プログラミング、管理を容易にするために、各モジュール。むしろ機械よりも、「習得して使用する」に手続きを書か

シングルトンデザインパターン、使用頻度が比較的高いです:プロジェクトを通して、このクラスに属する1つまたはいくつかの特別なクラス、オブジェクトがある、私はより多く作成しない、1を作成することができます。シングルトンクラスは、より具体的な文言で、プロジェクト全体は、プロファイルなどを動作させるために、一つだけを持つことができます。

シングルトン;

これはにクラスMyCAS //シングルトンクラス
{ 
プライベート:
    民営MyCAS(){} //コンストラクタ
                               //オブジェクトを作成できません
プライベート:
    静的MyCAS * m_instance; //静的メンバ変数

パブリック:
    静的MyCASでGetInstance *()
    { 
         IF(m_instance == nullptr A)
             { 
                 m_instance新しい新しいMyCAS =(); 
              } 
          戻りm_instance; 
    } 
}。

 主な機能に加えて、クラス静的変数の初期化

MyCAS * MyCAS :: m_instance = nullptr; //初期化静的変数

 主な機能には

MyCAS * P_A = MyCAS ::でGetInstance(); //オブジェクトを作成し、それはクラスオブジェクトへのポインタを返します

    書き込みMyCASの場合* P_B = MyCAS ::でGetInstance()、まだこの時点で同じインスタンスに、唯一のリターンオブジェクトポインタへ。

書かれたデストラクタは、この時点では、元のクラスの書き込みデストラクタコードは、オブジェクトを解放するために、カテゴリの新しいクラス、クラスの集合与えられています。

パブリック:
    静的MyCASでGetInstance *()
    { 
         IF(m_instance == nullptr A)
             { 
                 m_instance新しい新しいMyCAS =(); 
                 静的GarRelease Clであり; //プログラム終了クラスデストラクタが自動的にリソースを解放する際
              } 
          戻りm_instanceを; 
    } 

   クラスGarRelease 
   { 
          GarRelease〜()
          { 
              IF(MyCAS :: m_instance)
             { 
                 削除MyCAS :: m_instance; 
                 MyCAS :: = nullptr A m_instance; 
             } 
          } 
    }。

  要約:民営コンストラクタので、オブジェクトは、オブジェクトによって直接生成することができない、静的によって生成することができ、オブジェクトへのポインタで構成され、クラス全体は、設計パターンを書き込まれます。

共有データ分析

シングルトンは、問題に直面していないデータが読み取り専用である場合、でGetInstanceは、複数のスレッドによって使用され、複数のスレッド間での相互排他が、問題があり、シングルトンオブジェクトを作成するときに前のオブジェクト作成されます初期化、データのロード、その後の読み取り専用。

実用的な問題に直面する可能性があります。私たちが作成した独自のスレッドでシングルトンクラスを作成する必要があり、このスレッドは、複数のです。

必要に応じて)(顔に相互に排他的でGetInstanceが必要な場合があります:

同じ入力機能を持つ2つのスレッドの場合:

ボイドmyThread()
{ 
    MyCAS * P_A = MyCAS ::でGetInstance()。
}

  そこに問題になります:2つのスレッドが同じエントリの関数であるが、二つのスレッド、エントリ関数が何であるかに関係なく、手段は二つのプロセス二つのスレッド(パス)は、この機能を実行するために始めたこと、そして相互が必要除外量は、同時にでGetInstance()関数を呼び出す複数のスレッドを防ぎます

std :: unique_lockの<はstd ::ミューテックス> mymutex(resource_mutex); //は、の範囲を、自動的にロック自動的にロック解除外部

  プログラムが終了し、彼らは憎悪となり、プログラムの呼び出し元が頻繁に使用されている場合、効率が非常に低く、オブジェクトポインタを取得するには、)(GetInstaneを呼び出す必要がありますを完了するために多くの場所があります。場合決意条件をラップの最外層:

!(m_instance = nullptr)条件が満たされている場合A)は、その後、確かにそれは新しいm_instanceが渡されました表わします。

(m_instance == nullptr)条件が満たされた場合b)は、平均m_instanceはあまりにも新しいされていてはいけませんしません。

C)二重ロック。

    静的MyCAS *でGetInstance()
    { 
         IF(m_instance == nullptr)
         { 
            のstd :: unique_lockの<はstd ::ミューテックス> mymutex(source_mutex)
            IF(m_instance == nullptr)
             { 
                 m_instance =新しいMyCAS()。
                 静的GarRelease CL;                  
              }                 
          } 
          戻りm_instance。
    }

  

なcall_once

STD ::なcall_once()は関数テンプレートであり、C ++ 11の機能を導入し、これは、二番目の引数は、関数名であり、そして第2のパラメータは、確実にするために関数A()、なcall_once()関数の名前であります例えば、2件のスレッドがあり、一旦、呼び出された関数が呼び出されている、なcall_onceは、機能を確保することができるであろう場合には、共有データコードのコア場合にのみ、一度呼び出され、通常の環境下で2回呼び出されています(新しいオブジェクト)。

シングルトンオブジェクトの場合にはマルチスレッドで、初期化がなcall_onceミューテックスは、この機能を含むが、ミューテックス消費効率より少ないリソース、ミューテックスを必要とします。なcall_onceは、マーカーと組み合わせて使用​​する、のstd :: once_flag、実際には、このマークとして見ることができる構造です。このフラグの適用後に、対応する関数呼び出しなcall_once成功を実行するかどうかを決定するために、なcall_onceフラグの状態は、後続の呼なcall_onceは再び()、限りフラグは「呼び出し」状態に設定されていると呼ばれている入れ、次いで、対応する機能それが実行されないでしょう。

std :: once_flag g_flag; //これは、システム定義のタグであります

 完全な言葉遣い

MyCASクラス
{ 
    静的ボイドのCreateInstance(); //関数を一度呼び出される
     { 
          m_instance新しい新しいMyCAS =(); 
          静的GarRelease Clであり; 
     } 
     静的MyCASでGetInstance *()
    { 

          なcall_onceのSTD ::(g_flag、のCreateInstance); 
          戻りm_instance。
    } 

}

  2つのスレッドが同時にでGetInstanceを開始したと仮定()、STDの実装ながら::なcall_once()、ロックのようなcall_onceは、スレッドの呼び出しているだけかどうかを決定するために、現在のスレッドが終了し、別のスレッドを待たなければなりませんCreateInstance()を呼び出し、この時点ではなcall_onceマークが変更されました。

 

リファレンス

https://study.163.com/course/courseLearn.htm?courseId=1006067356#/learn/video?lessonId=1053491360&courseId=1006067356

おすすめ

転載: www.cnblogs.com/rynerlute/p/11829520.html