Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

基于c++11标准的线程单例类的实现

p__n 2019-12-25 12:09:34 阅读数:26 评论数:0 点赞数:0 收藏数:0

/最近乱七八糟的事情实在太多了,很多天都没有写博客。今天下午还要出差,头疼。/

在阅读陈硕大佬的muduo库时,其中EventLoop类是要求每个线程单例的,因此自己实现了这个机制,用类似于enable_shared_from_this模板类的方式使用,使代码更整洁。代码见github:
https://github.com/chloropn/c...

模板类one_object_per_thread的模板参数就是需要实现线程单例的类,实例化后的基类具有一个私有对象:std::string thread_id_用来记录构造时的线程id,一个thread_local的静态对象 T* object_,记录该线程唯一的对象指针。
当构造对象时,如果object_不为空指针,意味着该线程已经有一个该类型的对象,抛出异常。否则object_记录构造的本对象,并记录当前线程id。
该模板类的实例化类不允许拷贝构造和拷贝赋值以及移动赋值,显然需要用到这些函数的时候,线程内至少存在了两个即以上的对象,这本身就是不允许的,所以这些函数都被delete掉了,但允许在同一线程内移动构造。这时object_记录的对象将是新构造的对象,线程id不变。
该模板类提供了三个工具函数:一个静态函数get_object(),获取本线程存储的单例对象,一个成员函数assert_in_create_thread(),通过返回的bool值判断当前函数是否在构造线程中执行,一个成员函数get_create_thread-id()用来获取本对象构造线程的id。
以上,关于不支持线程间对象的移动和赋值的原因,由于object_的存储类型是thread_local,这意味着在一个线程中是无法修改其他线程的object_的,copy construct和copy assignment倒还好说,不需要修改传入对象的object_,但是移动操作意味着传入对象其构造线程的object_应该重新修改为nullptr(放在析构函数中?),这需要进一步的设计和考虑。

class YourClass : public one_object_per_thread<YourClass> {
...
}
版权声明
本文为[p__n]所创,转载请带上原文链接,感谢
https://segmentfault.com/a/1190000021394637