muduoネットワークライブラリのソースコードの再現ノート(10):baseライブラリのThreadLocalSingleton.h

2827 ワード

Muduoネットワークライブラリの概要
muduoはReactorモードに基づく現代C++ネットワークライブラリであり,著者の陳碩である.非ブロックIOモデルを採用し、イベント駆動とコールバックに基づいて、原生はマルチコアマルチスレッドをサポートし、Linuxサービスエンドマルチスレッドネットワークアプリケーションの作成に適しています.muduoネットワークライブラリのコアコードは数千行しかなく、ネットワークプログラミング技術学習の段階では、muduoは非常に学習に値するオープンソースライブラリである.現在、私もこのネットワークライブラリのソースコードを勉強し始めたばかりで、この学習過程を記録したいと思っています.このネットワークライブラリのソースコードはGitHubに公開されており、ここをクリックして読むことができます.現在Github上のこのソースコードは作者にc++11で書き換えられており、私が勉強しているバージョンはc++11バージョンを使用していません.しかし、両者は大同小異で、核心思想は変化していない.ここをクリックして私のソースコードを見ることができて、もしあなたが私の前のブログに興味があれば、次の接続をクリックすることができます:muduoネットワークライブラリのソースコードの再現ノート(一):baseライブラリのTimestamp.h muduoネットワークライブラリソースコード再現ノート(二):baseライブラリのAtomic.h muduoネットワークライブラリソースコード再現ノート(三):baseライブラリのException.h muduoネットワークライブラリソースコード再現ノート(四):baseライブラリのThread.hとCurrentThread.h muduoネットワークライブラリソースコード再現ノート(五):baseライブラリのMutex.hとCondition.hとCoutntDownLatch.h muduoネットワークライブラリソースコード再現ノート(六):baseライブラリのBlockingQueue.hとBoundedBlockingQueue.h muduoネットワークライブラリソースコード再現ノート(七):baseライブラリのThreadPool.h muduoネットワークライブラリソースコード再現ノート(八):baseライブラリのSingleton.h muduoネットワークライブラリソースコード再現ノート(九):baseライブラリのThreadLocalSingleton.h
ThreadLocalSingleton.h
前に単一類Singletonについて述べた.スレッドのローカルクラスhは、グローバル単一例とスレッドローカルデータをカプセル化する方法をそれぞれ提供する.グローバルな単一の例を使用して、各スレッド内にスレッドのローカルデータを提供する必要がある場合.このように書くことができます
muduo::Singleton>::instance.value()

このような実現は少し不自然で、muduoライブラリは単独でこのようなクラスを実現した.これは今日言ったThreadLocalSingletonである.h.このクラスの実装は難しくありません.コードを見てみましょう.
template
class ThreadLocalSingleton : boost::noncopyable
{
public:
	static T& instance()
	{
		if(!t_value_)
		{
			t_value_ = new T();
			deleter_.set(t_value_);
		}
		return *t_value_;
	}
	
	static T* pointer()
	{
		return t_value_;
	}
private:
	static void destructor(void* obj)
	{
		assert(obj == t_value_);
		typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
		delete t_value_;
		t_value_ = 0;
	}

	class Deleter
	{
	public:
		Deleter()
		{
			pthread_key_create(&pkey_,&ThreadLocalSingleton::destructor);
		}

		~Deleter()
		{
			pthread_key_delete(pkey_);
		}

		void set(T* newObj)
		{
			assert(pthread_getspecific(pkey_) == NULL);
			pthread_setspecific(pkey_,newObj);
		}
		pthread_key_t pkey_;	
	};
	static __thread T* t_value_;
	static Deleter deleter_;
};

template
__thread T* ThreadLocalSingleton::t_value_ = 0;

template
typename ThreadLocalSingleton::Deleter ThreadLocalSingleton::deleter_;

deleter_
deleter_クラスにネストされたクラスで、pthread_がカプセル化されています.key_tの関連操作、この部分の知識はThreadLocal.hのブログでは詳しく話しています.
インストール方法
instanceメソッドはスレッドのローカルインスタンスを返し、使用するメソッドとThreadLocal.h法は似ている.pthread_key_tはすべてのスレッドで同一であり、異なるスレッドに対応するvalue値が異なる(pthread_setspcific()とpthread_getspecific()設定)は、key多値の効果を達成します.