歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> POSIX線程的私有數據

POSIX線程的私有數據

日期:2017/3/1 11:17:56   编辑:Linux編程
多線程環境下,數據空間由所有線程共享。所以,一般意義上的全局變量也為所有的線程所共享。

有時需要提供線程私有的全局變量:
- 可以跨多個函數訪問(全局);
- 僅在某個線程有效(私有)。

比如程序可能需要每個線程都維護一個鏈表,維護手段相同,鏈表內的數據卻不同。

這樣的數據結構可由POSIX線程庫維護,稱為Thread Specific Data,簡稱TSD。

  1. #ifdef WIN32
  2. #include <windows.h>
  3. #define SLEEP(ms) Sleep(ms)
  4. #else if defined(LINUX)
  5. #include <stdio.h>
  6. #define SLEEP(ms) sleep(ms)
  7. #endif
  8. #include <pthread.h>
  9. pthread_key_t key;
  10. void echomsg(void * value)
  11. {
  12. printf("[CHILD THREAD] Destructor excuted, param=%s\n", (char *)value);
  13. }
  14. void * child1(void *arg)
  15. {
  16. printf("[CHILD THREAD - 1] Thread enter\n");
  17. pthread_setspecific(key, arg);
  18. SLEEP(2);
  19. printf("[CHILD THREAD - 1] Thread returns %s\n", (char *)pthread_getspecific(key));
  20. pthread_exit(NULL);
  21. return NULL;
  22. }
  23. void * child2(void *arg)
  24. {
  25. printf("[CHILD THREAD - 2] Thread enter\n");
  26. pthread_setspecific(key, arg);
  27. SLEEP(1);
  28. printf("[CHILD THREAD - 2] Thread returns %s\n", (char *)pthread_getspecific(key));
  29. return NULL;
  30. }
  31. static const char * msg[2] =
  32. {
  33. "Lazy cat",
  34. "Brown dog"
  35. };
  36. int main(int argc, char* argv[])
  37. {
  38. printf("[MAIN THREAD] Hello\n");
  39. pthread_key_create(&key, echomsg);
  40. pthread_t tid1,tid2;
  41. pthread_create(&tid1, NULL, child1, (void *)msg[0]);
  42. pthread_create(&tid2, NULL, child2, (void *)msg[1]);
  43. pthread_join(tid1, NULL);
  44. pthread_join(tid2, NULL);
  45. pthread_key_delete(key);
  46. printf("[MAIN THREAD] Exit\n");
  47. return 0;
  48. }
● 創建
int pthread_key_create (pthread_key_t * key, void (*destructor) (void *))

在Linux中,TSD池用一個結構數組實現:
static struct pthread_key_struct pthread_keys[PTHREAD_KEYS_MAX] = {{0, NULL}};

創建一個TSD就相當於將結構數組中的某一項設置為"in use"狀態,並將其索引返回給*key,然後設置destructor函數。

從中也可以看出,TSD的數目有上限:PTHREAD_KEYS_MAX。定義於/usr/include/bits/local_lim.h,一般為1024。

不要在destructor裡調用pthread_exit函數。

● 注銷
int pthread_key_delete (pthread_key_t key)

該函數並不檢查當前是否有線程正使用該TSD,也不會調用清理函數(destructor),只是將TSD釋放以供下一次pthread_key_create()使用。
在LinuxThreads中,它還會將與之相關的線程數據項設為NULL。

● 讀寫
int pthread_setspecific (pthread_key_t key, const void *value)
void * pthread_getspecific (pthread_key_t key)
Copyright © Linux教程網 All Rights Reserved