成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux多線程可重入函數(shù)

系統(tǒng) Linux
隨著多線程程序的逐漸流行,除了這種利用系統(tǒng)機(jī)制保護(hù)線程私有數(shù)據(jù)的方法,還有一部分人重新編寫了一些多線程庫(kù)函數(shù),這些函數(shù)的主要特點(diǎn)就是實(shí)現(xiàn)了算法和數(shù)據(jù)的分離,函數(shù)內(nèi)部只負(fù)責(zé)實(shí)現(xiàn)算法,需要的數(shù)據(jù)由線程傳入,這樣就保證了函數(shù)的多線程安全。

Reentrant和Thread-safe

在單線程程序中,整個(gè)程序都是順序執(zhí)行的,一個(gè)函數(shù)在同一時(shí)刻只能被一個(gè)函數(shù)調(diào)用,但在多線程中,由于并發(fā)性,一個(gè)函數(shù)可能同時(shí)被多個(gè)函數(shù)調(diào)用,此時(shí)這個(gè)函數(shù)就成了臨界資源,很容易造成調(diào)用函數(shù)處理結(jié)果的相互影響,如果一個(gè)函數(shù)在多線程并發(fā)的環(huán)境中每次被調(diào)用產(chǎn)生的結(jié)果是不確定的,我們就說這個(gè)函數(shù)是"不可重入的"/"線程不安全"的。為了解決這個(gè)問題,POSIX多線程庫(kù)提出了一種機(jī)制,用來解決多線程環(huán)境中的線程數(shù)據(jù)私有化問題,這套機(jī)制的主要思想是利用同步和互斥維護(hù)一個(gè)同名不同值的表,這個(gè)表會(huì)維護(hù)每個(gè)線程自己的資源地址,表面上是同一個(gè)變量,實(shí)質(zhì)上這個(gè)變量在不同的線程中的地址是不一樣,這樣就保證了每個(gè)線程其實(shí)都在使用自己的資源,實(shí)現(xiàn)了"thread-safe"。

其實(shí),隨著多線程程序的逐漸流行,除了這種利用系統(tǒng)機(jī)制保護(hù)線程私有數(shù)據(jù)的方法,還有一部分人重新編寫了一些多線程庫(kù)函數(shù),這些函數(shù)的主要特點(diǎn)就是實(shí)現(xiàn)了算法和數(shù)據(jù)的分離,函數(shù)內(nèi)部只負(fù)責(zé)實(shí)現(xiàn)算法,需要的數(shù)據(jù)由線程傳入,這樣就保證了函數(shù)的多線程安全,eg

  1. char *asctime(const struct tm *tm); 
  2. char *asctime_r(const struct tm *tm, char *buf);    //這個(gè)就是asctime的thread-safe版,有_r后綴 

但由于接口不同,完全重寫的函數(shù)推廣尚需時(shí)日。

當(dāng)下用的更多的是使用_REENTRANT來在原來的函數(shù)的基礎(chǔ)上改造,如果編譯的時(shí)候定義了這個(gè)宏,相關(guān)的庫(kù)函數(shù)就會(huì)被編譯成"thread-safe"的版本。

模型

如果要查看這些函數(shù)的man手冊(cè),可以安裝相關(guān)的man手冊(cè)

  1. pthread_key_t key           //創(chuàng)建用于保護(hù)線程私有資源的 
  2. keypthread_once_t once_key     //創(chuàng)建用于初始化key的once_key,要求用PTHREAD_INIT_ONCE來賦值,否則結(jié)果不確定 
  3.  
  4. pthread_key_create()        //創(chuàng)建 
  5. keypthread_once()              //初始化 
  6. keypthread_getspedifc()        //從key表中獲得線程私有資源的地址 
  7.  
  8. pthread_setspedifc()        //將線程私有資源的地址放到key中... 

例子

表面上每個(gè)函數(shù)調(diào)用了reverse()都會(huì)得到rev的地址,其實(shí)這個(gè)rev地址在不同的線程中并不相同,一旦一個(gè)線程調(diào)用了reverse()函數(shù),函數(shù)首先會(huì)到key標(biāo)識(shí)的表中去搜索這個(gè)線程以前是否調(diào)用過這個(gè)函數(shù),如果調(diào)用過,就將表中屬于這個(gè)線程的rev地址返回,如果沒有,就分配rev,并將該線程和它的專屬rev地址注冊(cè)到表中,這樣就把reverse()打造成了一個(gè)可重入的函數(shù)。 

  1. #include<stdio.h> 
  2. #include<pthread.h> 
  3. #include<stdlib.h> 
  4. #include<string.h> 
  5.  
  6. pthread_key_t key
  7. pthread_once_t once_key=PTHREAD_ONCE_INIT; 
  8.  
  9. #ifdef _REENTRANT 
  10. void myDestructor(void*p){ 
  11.     free(p); 
  12. void myCreateKey(void){    //創(chuàng)建key 
  13.     pthread_key_create(&key,myDestructor); 
  14. #endif 
  15.  
  16. char* reverse(char* buf,int len){ 
  17. #ifdef _REENTRANT 
  18.     //初始化key 
  19.     pthread_once(&once_key,myCreateKey);  //從key中獲取一個(gè)thread-specific的數(shù)據(jù) 
  20.     char* rev=(char*)pthread_getspecific(key); 
  21.     if(NULL==rev){ 
  22.         rev=(char*)malloc(len+1);        //將thread-specific的數(shù)據(jù)放到key中 
  23.         pthread_setspecific(key,rev); 
  24.     } 
  25. #else 
  26.     static char rev[100]; 
  27. #endif 
  28.     bzero(rev,sizeof(rev));    //翻轉(zhuǎn)buf 
  29.     while(len--) 
  30.         rev[len]=*buf++; 
  31.     return rev; 
  32. void* fcn1(void* p){ 
  33.     while(1){ 
  34.         char buf[100]="123456789"
  35.         printf("[%lu]:%s\n",pthread_self(),buf); 
  36.         char* rev=reverse(buf,strlen(buf)); 
  37.         sleep(1); 
  38.         printf("[%lu]:%s\n",pthread_self(),rev); 
  39.     } 
  40.  
  41. void* fcn2(void* p){ 
  42.     while(1){ 
  43.         char buf[100]="abcdef"
  44.         printf("[%lu]:%s\n",pthread_self(),buf);         
  45.         char* rev=reverse(buf,strlen(buf)); 
  46.         sleep(2);         
  47.         printf("[%lu]:%s\n",pthread_self(),rev); 
  48.  
  49.     } 
  50. }int main(int argc, const char *argv[]){ 
  51.     pthread_t tid[4]; 
  52.     pthread_create(&tid[0],NULL,fcn1,NULL); 
  53.     pthread_create(&tid[1],NULL,fcn2,NULL); 
  54.     pause();     
  55.     return 0; 
  56.  
責(zé)任編輯:龐桂玉 來源: 嵌入式Linux中文站
相關(guān)推薦

2011-06-22 16:02:37

Qt 多線程 重入

2011-06-22 14:38:09

QT 多線程 線程安全

2020-10-08 18:49:47

函數(shù)可重入不可重入

2011-06-22 14:47:51

QT 多線程 QObject

2020-11-10 07:46:58

函數(shù)printf 數(shù)據(jù)

2022-12-31 09:42:14

超時(shí)功能

2010-01-21 11:27:30

linux多線程機(jī)制線程同步

2021-05-11 14:50:21

ReentrantLo可重入鎖Java

2010-01-21 11:25:44

linux多線程線程資源

2012-11-12 09:26:06

.NET多線程

2018-06-26 05:23:19

線程安全函數(shù)代碼

2021-12-15 07:49:22

Go語言設(shè)計(jì)

2021-04-28 09:55:52

JavaLock接口并發(fā)編程

2010-01-21 11:23:49

Linux多線程同步消息隊(duì)列

2013-12-02 17:33:20

Linux進(jìn)程多線程

2010-01-21 11:22:35

Linux多線程同步

2009-03-12 10:52:43

Java線程多線程

2017-03-08 14:18:37

Linux多線程編程

2024-07-05 08:32:36

2025-06-25 06:18:46

Linux多線程機(jī)制
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲福利网站 | 精品一区二区在线观看 | 亚洲高清网 | 亚洲视频自拍 | 欧美精品在线观看 | 精品在线观看一区二区 | 久久国产亚洲 | 一级毛片免费视频观看 | 国产成人午夜电影网 | 日韩视频专区 | 免费在线观看成人av | 密室大逃脱第六季大神版在线观看 | 国产成人在线视频 | jizjizjiz中国护士18| 欧美亚洲一区二区三区 | 99久久婷婷 | 午夜免费小视频 | 天天想天天干 | 中文字幕亚洲无线 | 麻豆一区二区三区精品视频 | 成人免费一区二区三区视频网站 | 亚洲免费精品 | 综合久久99 | 羞羞色视频 | 一区不卡在线观看 | 91精品久久久久久综合五月天 | www成人啪啪18| 国产精品女人久久久 | 国产成人一区二区 | 久久久免费在线观看 | 午夜一区 | 欧美成人精品一区二区男人看 | 永久免费av | 免费在线成人网 | 精品久久久久久亚洲综合网站 | 国产一级精品毛片 | 免费在线观看黄色av | 九九热在线观看 | 韩三级在线观看 | 在线黄| 欧美一区二区成人 |