Posix執行緒程式設計指南(2)-執行緒私有資料 (轉)
Linux/thread/posix_thread/part2/author1">楊沙洲
2001 年 10 月
這是一個關於Posix執行緒的專欄。作者在闡明概念的基礎上,將向您詳細講述Posix執行緒庫API。本文是第二篇將向您講述執行緒的私有資料。
在單執行緒中,我們經常要用到"全域性變數"以實現多個間共享資料。在多執行緒環境下,由於資料空間是共享的,因此全域性變數也為所有執行緒所共有。但有時應用中有必要提供執行緒私有的全域性變數,僅在某個執行緒中有效,但卻可以跨多個函式訪問,比如程式可能需要每個執行緒維護一個連結串列,而使用相同的函式操作,最簡單的辦法就是使用同名而不同變數地址的執行緒相關資料結構。這樣的資料結構可以由Posix執行緒庫維護,稱為執行緒私有資料(Thread-specific Data,或TSD)。
Posix定義了兩個API分別用來建立和登出TSD:
int pthread_key_create(pthread_key_t *key, void (*destr_function) (void *))
該函式從TSD池中分配一項,將其值賦給key供以後訪問使用。如果destr_function不為空,線上程退出(pthread_exit())時將以key所關聯的資料為引數destr_function(),以釋放分配的緩衝區。
不論哪個執行緒呼叫pthread_key_create(),所建立的key都是所有執行緒可訪問的,但各個執行緒可根據自己的需要往key中填入不同的值,這就相當於提供了一個同名而不同值的全域性變數。在LinuxThreads的實現中,TSD池用一個結構陣列表示:
static struct pthread_key_struct pthread_keys[PTHREAD_KEYS_MAX] = { { 0, NULL } };
建立一個TSD就相當於將結構陣列中的某一項設定為"in_use",並將其返回給*key,然後設定destructor函式為destr_function。
登出一個TSD採用如下API:
int pthread_key_delete(pthread_key_t key)
這個函式並不檢查當前是否有執行緒正使用該TSD,也不會呼叫清理函式(destr_function),而只是將TSD釋放以供下一次呼叫pthread_key_create()使用。在LinuxThreads中,它還會將與之相關的執行緒資料項設為NULL(見"訪問")。
TSD的讀寫都透過專門的Posix Thread函式進行,其API定義如下:
int pthread_setspecific(pthread_key_t key, const void *pointer) void * pthread_getspecific(pthread_key_t key)
寫入(pthread_setspecific())時,將pointer的值(不是所指的內容)與key相關聯,而相應的讀出函式則將與key相關聯的資料讀出來。資料型別都設為void *,因此可以指向任何型別的資料。
在LinuxThreads中,使用了一個位於執行緒描述結構(_pthread_descr_struct)中的二維void *指標陣列來存放與key關聯的資料,陣列大小由以下幾個宏來說明:
#define PTHREAD_KEY_2NDLEVEL_SIZE 32 #define PTHREAD_KEY_1STLEVEL_SIZE ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1) / PTHREAD_KEY_2NDLEVEL_SIZE) 其中在/usr/include/bits/local_lim.h中定義了PTHREAD_KEYS_MAX為1024,因此一維陣列大小為32。而具體存放的位置由key值經過以下計算得到: idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE
也就是說,資料存放與一個32×32的稀疏矩陣中。同樣,訪問的時候也由key值經過類似計算得到資料所在位置索引,再取出其中內容返回。
以下這個例子沒有什麼實際意義,只是說明如何使用,以及能夠使用這一機制達到執行緒私有資料的目的。
#include
給例程建立兩個執行緒分別設定同一個執行緒私有資料為自己的執行緒ID,為了檢驗其私有性,程式錯開了兩個執行緒私有資料的寫入和讀出的時間,從程式執行結果可以看出,兩個執行緒對TSD的修改互不干擾。同時,當執行緒退出時,清理函式會自動,引數為tid。
楊沙洲,男,現攻讀國防科大學院計算機方向博士學位。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-960909/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [短文速讀 -5] 多執行緒程式設計引子:程式、執行緒、執行緒安全執行緒程式設計
- 併發程式設計之多執行緒執行緒安全程式設計執行緒
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- 多執行緒程式設計基礎(一)-- 執行緒的使用執行緒程式設計
- Java多執行緒(2)執行緒鎖Java執行緒
- C#多執行緒程式設計-基元執行緒同步構造C#執行緒程式設計
- 多執行緒程式設計基礎(二)-- 執行緒池的使用執行緒程式設計
- Java併發程式設計之執行緒安全、執行緒通訊Java程式設計執行緒
- C#多執行緒程式設計實戰1.1建立執行緒C#執行緒程式設計
- python 多執行緒程式設計Python執行緒程式設計
- JavaScript多執行緒程式設計JavaScript執行緒程式設計
- Python多執行緒程式設計Python執行緒程式設計
- 程式執行緒篇——程式執行緒基礎執行緒
- 執行緒(2)執行緒
- 執行緒(一)——執行緒,執行緒池,Task概念+程式碼實踐執行緒
- 玩轉java多執行緒 之多執行緒基礎 執行緒狀態 及執行緒停止實戰Java執行緒
- 程式執行緒篇——執行緒切換(上)執行緒
- 程式執行緒篇——執行緒切換(下)執行緒
- 執行緒、執行緒與程式、ULT與KLT執行緒
- Android程式框架:執行緒與執行緒池Android框架執行緒
- java多執行緒程式設計chap1-2Java執行緒程式設計
- 程式設計規範-父子執行緒必須放在不同的執行緒池中程式設計執行緒
- java多執行緒程式設計:你真的瞭解執行緒中斷嗎?Java執行緒程式設計
- 多執行緒程式設計總結:一、認識多執行緒本質執行緒程式設計
- Java併發程式設計之執行緒篇之執行緒中斷(三)Java程式設計執行緒
- Java併發程式設計之執行緒篇之執行緒簡介(二)Java程式設計執行緒
- 多執行緒(2)-執行緒同步互斥鎖Mutex執行緒Mutex
- Java多執行緒學習(2)執行緒控制Java執行緒
- 29. 多執行緒程式設計執行緒程式設計
- 多執行緒程式設計ExecutorService用法執行緒程式設計
- windows核心程式設計--執行緒池Windows程式設計執行緒
- 併發程式設計之:執行緒程式設計執行緒
- Rust 程式設計影片教程(進階)——016_2 建立執行緒與等待執行緒結束Rust程式設計執行緒
- springboot配置執行緒池使用多執行緒插入資料Spring Boot執行緒
- 物聯網學習教程—— 執行緒私有資料執行緒
- 執行緒與多執行緒執行緒
- 多執行緒【執行緒池】執行緒
- 執行緒和執行緒池執行緒
- 多執行緒--執行緒管理執行緒