muduo网络库源码复现笔记(十):base库的ThreadLocalSingleton.h

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和线程局部类ThreadLocal.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方法

instance方法返回一个线程局部实例,所用的方法和ThreadLocal.h方法相似。 pthread_key_t在所有的线程都是同一个的,对于不同的线程对应的value值是不同的(通过pthread_setspcific()和pthread_getspecific()设置),达到了一key多值的效果。

你可能感兴趣的:(muduo)