|新しいページ|検索|ページ一覧|RSS|@ウィキご利用ガイド | 管理者にお問合せ
|ログイン|

singleton × thread

    
※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

singleton × thread

last update: 2010/12/28 (Tue )

さて,この記事のテーマとは singleton と thread でどちらが攻めでどちらが○けか,ではない!

なんてタイトルをつけやがる….期待させて申し訳ないが(ありえない) Singleton とは,プログラム内でインスタンスが 1 つしか存在しないことを保証するクラスのこと. 要はグローバル変数の代わり.簡単なコードは以下の通り.

// singleton.h
#include <iostream>
#include <boost/thread.hpp>

class Singleton
{
private:
    Singleton() {
        std::cout << "Singleton : created" << std::endl;
    }
    Singleton(const Singleton&);            // コピー禁止
    Singleton& operator=(const Singleton&); // 代入禁止
public:
    ~Singleton() {
        std::cout << "Singleton : deleted" << std::endl;
    }
    // インスタンス取得関数
    static Singleton* getInstance();
};

// singleton.cpp
#include "singleton.h"

Singleton* Singleton::getInstance()
{
    static Singleton instance;
    return &instance;
}

さてここで疑問に思った.このインスタンス取得関数ってマルチスレッド安全なの?

調べると,「C では静的自動変数の初期化は,実行フローが最初に変数の宣言・初期化行を通過した時に行われる」とある.ならば Singleton のコンストラクタが何やら時間のかかる処理をやるとして,あるスレッドが Singleton のコンストラクタにいる間に他のスレッドがインスタンス取得関数を呼んだらどうなるんだろう.

てことで実験.

// singleton.h
#include <iostream>
#include <boost/thread.hpp>

class Singleton
{
private:
    Singleton() {
        // 1000 ミリ秒かかる処理
        boost::thread::sleep(
           boost::get_system_time()
               + boost::posix_time::milliseconds(1000));
        std::cout << "Singleton : created" << std::endl;
    }
    Singleton(const Singleton&);            // コピー禁止
    Singleton& operator=(const Singleton&); // 代入禁止
public:
    ~Singleton() {
        std::cout << "Singleton : deleted" << std::endl;
    }
    // インスタンス取得関数
    static Singleton* getInstance();
};

// singleton.cpp
#include "singleton.h"
#include <cstdlib>

Singleton* Singleton::getInstance()
{
    static Singleton instance;
    return &instance;
}

void func()
{
    std::cout << "func : begin" << std::endl;
    // インスタンス取得関数の呼び出し
    Singleton* singleton = Singleton::getInstance();
    std::cout << "func : end" << std::endl;
}

int main(int argc, char* argv[])
{
    boost::thread th1( &func );
    boost::thread th2( &func );
    boost::thread th3( &func );
    
    th1.join();
    th2.join();
    th3.join();

    return EXIT_SUCCESS;
}

結果.

func : begin
func : begin
func : begin
Singleton : created # この直前で1秒固まる
func : end
func : end
func : end
Singleton : deleted

マルチスレッド安全でした *1 .なんだつまらん(笑)

&trackback

参考



コメント

  • コメントの投稿テスト -- (tossy_squirrel) 2010-12-29 03:35:18
名前:
コメント:

すべてのコメントを見る


関連ページ



関連ブログ

  • 「singleton」を含むブログが見つかりません。

プロフィール


tossy_squirrel



メニュー




更新履歴


取得中です。