muduo源码分析3——TSD
生活随笔
收集整理的這篇文章主要介紹了
muduo源码分析3——TSD
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1 什么是tsd
因為全局變量在所有線程中是共享的,如何才能擁有只在單個線程中共享的全局數據呢?這就需要tsd了。
可能會有疑問,這玩意到底有啥用,在線程中定義一個變量,其內部函數不也能使用嗎?但是其不是全局的,需要傳入到函數。
2 相關函數
int pthread_key_create(pthread_key_t *key, void (*destructor) (void *)) 創建成功返回0,失敗返回errnodestructor定義后,當線程結束時,會調用該函數來完成key指向內存清理
int pthread_key_delete(pthread_key_t key); 成功返回0,失敗返回errno man手冊解釋如下,cleanup操作可以在pthread_key_delete調用前后,pthread_key_delete只負責刪除key指針,但是cleanup是destructor函數完成It is the responsibility of the application to free any application storage or perform any cleanup actions for data structures related to the deleted key or associated thread-specific data in any threads; this cleanup can be done either before or after pthread_key_delete() is called. int pthread_setspecific(pthread_key_t key, const void *value); 成功返回0,失敗返回errno 設置key指向的值 void * pthread_getspecific(pthread_key_t key); 成功返回0,失敗返回errno 返回指向的值的指針3 測試代碼
下面寫了測試代碼
4 muduo中的tsd
4.1 muduo的tsd怎么用
value()函數做了如下工作
每次只需要調用value函數即可,完成get,set等操作。
// Use of this source code is governed by a BSD-style license // that can be found in the License file. // // Author: Shuo Chen (chenshuo at chenshuo dot com)#ifndef MUDUO_BASE_THREADLOCAL_H #define MUDUO_BASE_THREADLOCAL_H#include "muduo/base/Mutex.h" #include "muduo/base/noncopyable.h"#include <pthread.h>namespace muduo {template<typename T> class ThreadLocal : noncopyable {public:ThreadLocal(){MCHECK(pthread_key_create(&pkey_, &ThreadLocal::destructor));}~ThreadLocal(){MCHECK(pthread_key_delete(pkey_));}T& value(){T* perThreadValue = static_cast<T*>(pthread_getspecific(pkey_));if (!perThreadValue){T* newObj = new T();MCHECK(pthread_setspecific(pkey_, newObj));perThreadValue = newObj;}return *perThreadValue;}private:static void destructor(void *x){T* obj = static_cast<T*>(x);typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];T_must_be_complete_type dummy; (void) dummy;delete obj;}private:pthread_key_t pkey_; };} // namespace muduo#endif // MUDUO_BASE_THREADLOCAL_H4.2 muduo 測試代碼
#include "muduo/base/ThreadLocal.h" #include "muduo/base/CurrentThread.h" #include "muduo/base/Thread.h"#include <stdio.h>class Test : muduo::noncopyable {public:Test(){printf("tid=%d, constructing %p\n", muduo::CurrentThread::tid(), this);}~Test(){printf("tid=%d, destructing %p %s\n", muduo::CurrentThread::tid(), this, name_.c_str());}const muduo::string& name() const { return name_; }void setName(const muduo::string& n) { name_ = n; }private:muduo::string name_; };muduo::ThreadLocal<Test> testObj1; muduo::ThreadLocal<Test> testObj2;void print() {printf("tid=%d, obj1 %p name=%s\n",muduo::CurrentThread::tid(),&testObj1.value(),testObj1.value().name().c_str());printf("tid=%d, obj2 %p name=%s\n",muduo::CurrentThread::tid(),&testObj2.value(),testObj2.value().name().c_str()); }void threadFunc() {print();testObj1.value().setName("changed 1");testObj2.value().setName("changed 42");print(); }int main() {testObj1.value().setName("main one");print();muduo::Thread t1(threadFunc);t1.start();t1.join();testObj2.value().setName("main two");print();pthread_exit(0); } lxz@lxz-VirtualBox:~/liuxz/testmuduo/threadlocal/build$ ./thread_local tid=2665, constructing 0x55b96a73ee70 tid=2665, obj1 0x55b96a73ee70 name=main one tid=2665, constructing 0x55b96a73f2b0 tid=2665, obj2 0x55b96a73f2b0 name= tid=2666, constructing 0x7fd93c000b20 tid=2666, obj1 0x7fd93c000b20 name= tid=2666, constructing 0x7fd93c000b50 tid=2666, obj2 0x7fd93c000b50 name= tid=2666, obj1 0x7fd93c000b20 name=changed 1 tid=2666, obj2 0x7fd93c000b50 name=changed 42 tid=2666, destructing 0x7fd93c000b20 changed 1 tid=2666, destructing 0x7fd93c000b50 changed 42 tid=2665, obj1 0x55b96a73ee70 name=main one tid=2665, obj2 0x55b96a73f2b0 name=main two tid=2665, destructing 0x55b96a73ee70 main one tid=2665, destructing 0x55b96a73f2b0 main two總結
以上是生活随笔為你收集整理的muduo源码分析3——TSD的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 陕西山阳中学2021高考成绩查询,陕西高
- 下一篇: 数论之杨辉三角