使用C語言怎么對線程對象和線程進行存儲?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
C語言是一門面向過程的、抽象化的通用程序設計語言,廣泛應用于底層開發(fā),使用C語言可以以簡易的方式編譯、處理低級存儲器。
使用線程對象
線程對象是在聲明中包含新存儲類修飾符 _Thread_local 的全局或靜態(tài)對象。這意味著:每一個線程擁有屬于自己的線程對象實例,它在線程啟動時創(chuàng)建并初始化。對象的存儲周期等于線程的運行時間。在一個線程內(nèi)表達式里面的線程對象名,將引用這個對象在當前線程下的本地實例。
修飾符 _Thread_local 可以與修飾符 static 或 extern 同時使用。頭文件 threads.h 定義了 thread_local 作為 _Thread_local 的同義詞。在例 1 中,主線程和新啟動線程各自擁有線程本地變量 var 的一個實例。
【例1】使用一個線程對象
#include <stdio.h> #include <threads.h> thread_local int var = 10; void print_var(void){ printf("var = %d\n", var); } int func(void *); // 線程函數(shù) int main(int argc, char *argv[]) { thrd_t th2; if ( thrd_create( &th2, func, NULL ) != thrd_success ){ fprintf(stderr,"Error creating thread.\n"); return 0xff; } print_var(); // 輸出:var = 10 thrd_join(th2, NULL); return 0; } int func(void *arg) // 線程函數(shù) { var += 10; // 線程本地變量 print_var(); // 輸出:var = 20 return 0 }
線程存儲技術要比線程對象更加靈活。例如,獨立線程可以使用不同大小的內(nèi)存。它們可以動態(tài)地分配內(nèi)存,并通過調(diào)用析構(gòu)函數(shù)再次釋放內(nèi)存。同時,可以使用相同的標識符訪問這些獨立線程所在的不同內(nèi)存區(qū)域。
這種靈活性通過初始創(chuàng)建一個全局的鍵(key)實現(xiàn),該鍵表示了一個指向線程存儲的指針。然后,獨立線程通過指定其線程存儲的位置加載這個指針。該全局鍵值是類型為 tss_t 的對象。頭文件 threads.h 包含了該類型的定義以及 4 個用于管理線程存儲(簡稱 TSS)函數(shù)的聲明:
int tss_create(tss_t*key,tss_dtor_t dtor);
通過析構(gòu)函數(shù) dtor 生成一個新的 TSS 指針,并且將 key 引用的對象設置為標識該 TSS 指針的值。類型 tss_dtor_t 是一個函數(shù)指針,定義為 void(*)(void*)(它指的是一個函數(shù)指針,該函數(shù)參數(shù)為 void 指針,并且該函數(shù)沒有返回值)。dtor 的返回值可以是一個空指針。
void tss_delete(tss_t key);
釋放 TSS 鍵 key 所使用的所有資源。
int tss_set(tss_t key,void*val);
對于調(diào)用 tss_set()的線程,將 key 所標識的 TSS 指針設置為 val 所引用的內(nèi)存地址。
void*tss_get(tss_t key);
返回指向內(nèi)存塊的指針,該內(nèi)存塊為正在調(diào)用的線程通過函數(shù) tss_set()設置。如果發(fā)生錯誤,tss_get()返回 NULL。
如果函數(shù) tss_create()和 tss_set()發(fā)生錯誤,則返回 thrd_error;否則,返回 thrd_success。
例 2 中的程序在動態(tài)分配的線程存儲中,保留線程的名稱。
【例2】使用線程存儲
#include <threads.h> #include <stdio.h> #include <stdlib.h> #include <string.h> tss_t key; // 用于TSS指針的全局鍵 int thFunc(void *arg); // 線程函數(shù) void destructor(void *data); // 析構(gòu)函數(shù) int main(void) { thrd_t th2, th3; int result1 = 0, result2 = 0; // 創(chuàng)建一個TSS密鑰 if (tss_create(&key, destructor) != thrd_success) return -1; // 創(chuàng)建線程 if (thrd_create(&th2, thFunc, "Thread_1") != thrd_success || thrd_create(&th3, thFunc, "Thread_2") != thrd_success) return -2; thrd_join(th2, &result1); thrd_join(th3, &result2); if ( result1 != 0 || result2 != 0 ) fputs("Thread error\n", stderr); else puts("Threads finished without error."); tss_delete(key); // 釋放TSS指針所有的資源 return 0; } void print(void) // 顯示線程存儲 { printf( "print: %s\n", (char*)tss_get(key) ); } int thFunc( void *arg ) { char *name = (char*)arg; size_t size = strlen(name)+1; // 設置線程存儲 if ( tss_set(key, malloc(size)) != thrd_success ) return -1; // 存儲數(shù)據(jù) strcpy((char*)tss_get(key), name); print(); return 0; } void destructor(void *data) { printf("Destructor for %s\n", (char*)data); free(data); // 釋放內(nèi)存 }
關于使用C語言怎么對線程對象和線程進行存儲問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關知識。
名稱欄目:使用C語言怎么對線程對象和線程進行存儲-創(chuàng)新互聯(lián)
分享地址:http://vcdvsql.cn/article48/eioep.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、響應式網(wǎng)站、標簽優(yōu)化、自適應網(wǎng)站、關鍵詞優(yōu)化、移動網(wǎng)站建設
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容