TSD(Thread Specific Data)线程专有数据
(1)全局變量
(2)局部變量
(3)TSD(Thread-Specific Data 線程專有數據)
1.http://upczap.itpub.net/
在單線程的程序里,有兩種基本的數據:全局變量和局部變量。但在多線程程序里,還有第三種數據類型:線程數據(TSD: Thread-Specific Data)。它和全局變量很象,在線程內部,各個函數可以象使用全局變量一樣調用它,但它對線程外部的其它線程是不可見的。這種數據的必要性是顯而易見 的。例如我們常見的變量errno,它返回標準的出錯信息。它顯然不能是一個局部變量,幾乎每個函數都應該可以調用它;但它又不能是一個全局變量,否則在 A線程里輸出的很可能是B線程的出錯信息。要實現諸如此類的變量,我們就必須使用線程數據。我們為每個線程數據創建一個鍵,它和這個鍵相關聯,在各個線程 里,都使用這個鍵來指代線程數據,但在不同的線程里,這個鍵代表的數據是不同的,在同一個線程里,它代表同樣的數據內容。
2.http://bbs.chinaunix.net/viewthread.php?tid=941730
linux 多線程編程中引入了Thread-Specific Data(線程相關的數據)的概念
為什么需要"線程相關的數據"呢?怎樣使用"線程相關的數據"呢?
1. 為什么需要Thread-Specific Data "線程相關的數據"
這里只介紹我個人認為的一個原因, 當然它還有許多其他用途,歡迎大家討論
例子:實現同時運行兩個線程,對于每個線程,在該線程調用的每個函數中打印線程的名字,以及它正在調用的函數的名字.
(下面的例子與實現只是為了說明問題,有些地方可能不妥)
不使用"線程相關的數據"的兩種實現方法:
實現方法1. 不使用全局變量
#include <pthread.h>
#define MAXLENGTH 20
void another_func (const char * threadName)
{
??printf ("%s is running in another_func/n", threadName);
}
void * thread_func (void * args)
{
??char threadName[MAXLENGTH];
??strncpy (threadName, (char *)args, MAXLENGTH-1);
??
??printf ("%s is running in thread_func/n", threadName);
??another_func (threadName);
??
}
int main (int argc, char * argv[])
{
??pthread_t pa, pb;
??pthread_create ( &pa, NULL, thread_func, "Thread A");
??pthread_create ( &pb, NULL, thread_func, "Thread B");
??pthread_join (pa, NULL);
??pthread_join (pb, NULL);
}
輸出結果為:
Thread A is running in thread_func
Thread A is running in another_func
Thread B is running in thread_func
Thread B is running in another_func
該方法的缺點是:由于要記錄是哪一個線程在調用函數,每個函數需要一個額外的參數來
記錄線程的名字,例如another_func函數需要一個threadName參數
如果調用的函數多了,則每一個都需要一個這樣的參數
實現方法2. 使用全局變量
#include <pthread.h>
#define MAXLENGTH 20
char threadName[MAXLENGTH];
pthread_mutex_t sharedMutex=PTHREAD_MUTEX_INITIALIZER;
void another_func ()
{
??printf ("%s is running in another_func/n", threadName);
}
void * thread_func (void * args)
{
??pthread_mutex_lock(&sharedMutex);
??strncpy (threadName, (char *)args, MAXLENGTH-1);
??printf ("%s is running in thread_func/n", threadName);
??another_func ();
??pthread_mutex_unlock(&sharedMutex);
??
}
int main (int argc, char * argv[])
{
??pthread_t pa, pb;
??pthread_create ( &pa, NULL, thread_func, "Thread A");
??pthread_create ( &pb, NULL, thread_func, "Thread B");
??pthread_join (pa, NULL);
??pthread_join (pb, NULL);
}
該方法的缺點是:由于多個線程需要讀寫全局變量threadName,就需要使用互斥機制
分析以上兩種實現方法,Thread-Specific Data "線程相關的數據"的一個好處就體現出來了:
(1)"線程相關的數據"可以是一個全局變量,并且
(2)每個線程存取的"線程相關的數據"是相互獨立的.
2. 怎樣使用"線程相關的數據"
這是利用"線程相關的數據"的實現方式:
#include <pthread.h>
pthread_key_t p_key;
void another_func ()
{
??printf ("%s is running in another_func/n", (char *)pthread_getspecific(p_key));
}
void * thread_func (void * args)
{
??pthread_setspecific(p_key, args);
??printf ("%s is running in thread_func/n", (char *)pthread_getspecific(p_key));
??another_func ();
??
}
int main (int argc, char * argv[])
{
??pthread_t pa, pb;
??pthread_key_create(&p_key, NULL);
??
??pthread_create ( &pa, NULL, thread_func, "Thread A");
??pthread_create ( &pb, NULL, thread_func, "Thread B");
??pthread_join (pa, NULL);
??pthread_join (pb, NULL);
}
說明:
(1)
線程A, B共用了p_key,
通過p_key,就可以存取只跟當前線程相關的一個值(這個值由編譯器管理)
線程A----->p_key----->線程A相關的值(由編譯器管理)
線程B----->p_key----->線程B相關的值(由編譯器管理)
設置"線程相關的數據",使用
int pthread_setspecific(pthread_key_t key, const void *pointer);
讀取"線程相關的數據",使用
void * pthread_getspecific(pthread_key_t key);
注意到,這兩個函數分別有一個void類型的指針,我們的線程就是通過這兩個指針分別與
"線程相關的數據"的數據進行交互的
(2)
由于p_key是一個全局變量,
函數another_func不需要額外的參數就可以訪問它;
又因為它是"線程相關的數據", 線程A, B通過p_key存取的數據是相互獨立的,
這樣就不需要額外的互斥機制來保證數據訪問的正確性了.
總結
以上是生活随笔為你收集整理的TSD(Thread Specific Data)线程专有数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: COM(组件对象模型)
- 下一篇: Eclipse使用Android2.3和