亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 操作系統 > 正文

線程控制之重入

2024-06-28 13:28:12
字體:
來源:轉載
供稿:網友
線程控制之重入

有了信號處理程序和線程,多個控制線程在同一時間可能潛在地調用同一個函數。

如果一個函數在同一時刻可以被多個線程安全地調用,就稱該函數是線程安全的。在Single UNIX Specification中定義的所有函數,除了表12-5中列出的函數以外,其他函數都保證是線程安全的。另外,ctermid和tmpnam函數在參數傳入空指針時并不能保證是線程安全的。類似地,wcrtomb和wcsrtombs函數如果參數mbstate_t傳入的是空指針的話,也不能保證它們是線程安全的。

表12-5 POSIX.1中不能保證線程安全的函數(此表摘自第三版)

未命名

支持線程安全函數的操作系統實現會在<unistd.h>中定義符號_POSIX_THREAD_SAFE_FUNCTIONS。應用程序可以在sysconf函數中傳入_SC_THREAD_SAFE_FUNCTIONS參數,以在運行時檢查是否支持線程安全函數。所有遵循XSI的實現要求必須支持線程安全函數。

操作系統實現支持線程安全函數這一特性時,對POSIX.1中的一些非線程安全函數,它會提供可替代的線程安全版本,表12-6列出了這些函數的線程安全版本。很多函數并不是線程安全的,因為他們返回的數據是存放在靜態的內存緩沖區中。通過修改接口,要求調用者自己提供緩沖區可以使函數變為線程安全的。

表12-6 替代的線程安全函數(此表摘自第三版)

未命名

表12-6中列出的函數的命名方式與他們的非線程安全版本的名字相似,只不過在名字最后加了_r,以表明這個版本是可重入的。

如果一個函數對多個線程來說是可重入的,則說這個函數是線程安全的,但這并不能說明對信號處理程序來說該函數也是可重入的。如果函數對異步信號處理程序的重入是安全的,那么就可以說函數是異步-信號安全的。

除了表12-6中列出的函數,POSIX.1還提供了以線程安全的方式管理FILE對象的方法。可以使用flockfile和ftrylockfile獲取與給定FILE對象關聯的鎖。這個鎖是遞歸的,當占有這把鎖的時候,還可以再次獲取該鎖,這并不會導致死鎖。雖然這種鎖的具體實現并無規定,但要求所有操作FILE對象的標準I/O例程表現得就像它們內部調用了flockfile和funlockfile一樣。

#include <stdio.h>int ftrylockfile(FILE *fp);返回值:若成功則返回0,否則返回非0值void flockfile(FILE *fp);void funlockfile(FILE *fp);

雖然標準的I/O例程從它們各自的內部數據結構這一角度出發,可能是以線程安全的方式實現的,但有時把鎖開放給應用程序仍然是非常有用的。這允許應用程序把多個對標準I/O函數的調用組合成原子序列。當然,在處理多個FILE對象時,需要注意可能出現的死鎖,并且需要對所有的鎖仔細地排序。

如果標準I/O例程都獲取它們各自的鎖,那么在做一次一個字符的I/O操作時性能就會出現嚴重的下降。在這種情況下,需要對每一個字符的讀或寫操作進行獲取鎖和釋放鎖的動作。為了避免這種開銷,出現了不加鎖版本的基于字符的標準I/O例程。

#include <stdio.h>int getchar_unlocked(void);int getc_unlocked(FILE *fp);兩者的返回值都是:若成功則返回一個字符,若已到達文件結尾或出錯則返回EOFint putchar_unlocked(int c);int putc_unlocked(int c, FILE *fp);兩者的返回值都是:若成功則返回c,若出錯則返回EOF

除非被flockfile(或ftrylockfile)和funlockfile的調用包圍,否則盡量不要調用這四個函數,因為它們會導致不可預期的結果(即由多個控制線程非同步地訪問數據所引起的種種問題)。

一旦對FILE對象進行加鎖,就可以在釋放鎖之前對這些函數進行多次調用。這樣就可以在多次的數據讀寫上分攤總的加解鎖的開銷。

 實例

程序清單12-3顯示了getenv(http://www.CUOXin.com/nufangrensheng/p/3508319.html)一個可能的實現。因為所有調用getenv的線程返回的字符串都存放在同一個靜態緩沖區中,所以這個版本不是可重入的。如果兩個線程同時調用這個函數,就會看到不一致的結果。

程序清單12-3 getenv的非可重入版本

#include <limits.h>#include <signal.h>static char envbuf[ARG_MAX];extern char **environ;char *getenv(const char *name);{    int i, len;        len = strlen(name);    for(i = 0; environ[i] != NULL; i++)    {        if((strncmp(name, environ[i], len) == 0) &&           (environ[i][len] == '='))        {            strcpy(envbuf, &environ[i][len+1]);            return(envbuf);        }    }    return(NULL);}

程序清單12-4給出了getenv的可重入版本,這個版本命名為getenv_r。它使用pthread_once函數來確保每個進程只調用一次thread_init函數。

 程序清單12-4 getenv的可重入(線程安全)版本

#include <string.h>#include <errno.h>#include <pthread.h>#include <stdlib.h>extern char **environ;pthread_mutex_t env_mutex;static pthread_once_t init_done = PTHREAD_ONCE_INIT;static voidthread_init(void){    pthread_mutexattr_t attr;        pthread_mutexattr_init(&attr);    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);    pthread_mutex_init(&env_mutex, &attr);    pthread_mutexattr_destroy(&attr);}intgetenv_r(const char *name, char *buf, int buflen){    int i, len, olen;        pthread_once(&init_done, thread_init);    len = strlen(name);    pthread_mutex_lock(&env_mutex);    for(i = 0; environ[i][len] != NULL; i++)    {        if((strncmp(name, environ[i], len) == 0) &&          (environ[i][len] == '='))        {            olen = strlen(&environ[i][len+1]);            if(olen >= buflen)            {                pthread_mutex_unlock(&env_mutex);                return(ENOSPC);            }            strcpy(buf, &environ[i][len+1]);            pthread_mutex_unlock(&env_mutex);            return(0);        }    }    pthread_mutex_unlock(&env_mutex);    return(ENOENT);}

要使getenv_r可重入,需要改變接口,調用者必須自己提供緩沖區,這樣每個線程可以使用各自不同的緩沖區從而避免其他線程的干擾。但是注意這還不足以使getenv_r成為線程安全的,要使getenv_r成為線程安全的,需要在搜索請求的字符串時保護環境不被修改。我們可以使用互斥量,通過getenv_r和putenv函數對環境列表的訪問進行序列化。

可以使用讀寫鎖,從而允許對getenv_r的多次并發訪問,但并發性的增強可能并不會在很大程度上改善程序的性能。這里面有兩個原因:首先,環境列表通常不會很長,所以掃描列表時并不需要長時間地占有互斥量;其次,對getenv和putenv的調用不是頻繁發生的,所以改善它們的性能并不會對程序的整體性能產生很大的影響。

即使把getenv_r變成線程安全的,也并不意味著它對信號處理程序是可重入的。如果使用的是非遞歸的互斥量,當線程從信號處理程序中調用getenv_r時,就有可能出現死鎖。如果信號處理程序在線程執行getenv_r時中斷了該線程,由于這時已經占有加鎖的env_mutex,這樣其他線程試圖對這個互斥量的加鎖就會被阻塞,最終導致線程進入死鎖狀態。所以,必須使用遞歸互斥量阻止其他線程改變當前正在查看的數據結構,同時還要阻止來自信號處理程序的死鎖。問題是pthread函數并不保證是異步信號安全的,所以不能把pthread函數用于其他函數,讓該函數成為異步信號安全的。

本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日本在线视频中文字字幕| 色播久久人人爽人人爽人人片视av| 亚洲精品美女视频| 亚洲新声在线观看| 视频一区视频二区国产精品| 91亚洲精品久久久| 国产91精品视频在线观看| 日韩高清中文字幕| 国产亚洲精品激情久久| 韩国精品久久久999| 青青草原一区二区| 国产成人av在线播放| 亚洲精品视频网上网址在线观看| 亚洲第一精品夜夜躁人人爽| 日韩黄色av网站| 91在线视频精品| 亚洲最大中文字幕| 国产97在线亚洲| 欧美在线视频观看免费网站| 丝袜美腿亚洲一区二区| www.日韩不卡电影av| 精品视频www| 欧美丝袜美女中出在线| 欧美激情按摩在线| 亚洲深夜福利视频| 岛国av一区二区三区| 亚洲最新av在线网站| 在线观看成人黄色| 色伦专区97中文字幕| 久久免费少妇高潮久久精品99| 久久久久久久久综合| 欧美日韩国产专区| 久久久久久久久久久国产| 国产精品欧美日韩一区二区| 国产日韩精品一区二区| 国产精品美女999| 日韩的一区二区| 成人性生交大片免费观看嘿嘿视频| 亚洲电影免费观看高清完整版在线| 日本亚洲精品在线观看| 欧美在线视频导航| wwwwwwww亚洲| 欧美专区在线观看| 久久精品视频网站| 日韩精品视频观看| 91久久久精品| 亚州欧美日韩中文视频| 成人性生交大片免费观看嘿嘿视频| 亚洲缚视频在线观看| 日韩一区二区久久久| 日韩免费观看在线观看| 日韩大片免费观看视频播放| 国产日韩欧美日韩大片| 清纯唯美亚洲激情| 久久99精品久久久久久琪琪| 久久99国产精品自在自在app| www.美女亚洲精品| 欧美高清视频一区二区| 亚洲图片在区色| 久久艳片www.17c.com| 国产精品香蕉av| 欧美激情a∨在线视频播放| 欧美性猛xxx| 久久久电影免费观看完整版| 日韩美女免费视频| 欧美日韩国产麻豆| 日韩av免费在线| 亚洲一区二区三区四区在线播放| 亚洲人成网站999久久久综合| 久久91超碰青草是什么| 亚洲综合最新在线| 日韩成人免费视频| 亚洲国产成人久久综合| 91精品国产色综合| 国语对白做受69| 国产精品成人av性教育| 综合激情国产一区| 国产午夜精品美女视频明星a级| 欧美成人全部免费| 国产欧美在线视频| 91精品久久久久久综合乱菊| 亚洲开心激情网| 国产精品美女www爽爽爽视频| 国产精品视频一| 国产精品久久久久91| 国产香蕉精品视频一区二区三区| 最近中文字幕mv在线一区二区三区四区| 亚洲电影免费观看高清完整版在线观看| 91日本在线视频| 1769国产精品| 欧美精品少妇videofree| 91精品国产91久久久久久吃药| 热久久视久久精品18亚洲精品| 亚洲成人精品视频在线观看| 久久九九热免费视频| 青草热久免费精品视频| 国产精品久久久91| 亚洲男人天堂九九视频| 欧美激情中文字幕乱码免费| 亚洲精品日韩丝袜精品| 91天堂在线观看| 国产精品视频在线观看| 在线日韩日本国产亚洲| 精品中文字幕在线观看| 欧美理论电影在线播放| 久久九九全国免费精品观看| 久久精品国产久精国产思思| 日韩大胆人体377p| 日韩欧美福利视频| 丁香五六月婷婷久久激情| 精品无码久久久久久国产| 成人性生交大片免费看视频直播| 亚洲成人久久久| 精品亚洲男同gayvideo网站| 国产精品99导航| 91久久久亚洲精品| www.久久撸.com| 国产性猛交xxxx免费看久久| 亚洲精品电影久久久| 久久精品久久久久久国产 免费| 久久免费视频这里只有精品| 精品在线欧美视频| 欧美激情综合色综合啪啪五月| 欧美亚洲激情在线| 日本免费一区二区三区视频观看| 久久午夜a级毛片| 日韩成人av在线播放| 久久久91精品| 精品国内产的精品视频在线观看| 奇门遁甲1982国语版免费观看高清| 欧美精品在线免费观看| 色偷偷偷亚洲综合网另类| 欧美激情日韩图片| 欧美激情精品久久久久久免费印度| 亚洲欧洲激情在线| 久久大大胆人体| 亚洲精品短视频| 欧美激情免费观看| 日韩免费电影在线观看| 成人午夜在线视频一区| 伊人一区二区三区久久精品| 欧美三级欧美成人高清www| 国产精品美女www爽爽爽视频| 久久久久亚洲精品| 伊人av综合网| 国产精品自拍偷拍| 8x海外华人永久免费日韩内陆视频| 国产精品亚洲视频在线观看| 国产精品入口免费视频一| 91精品久久久久久久| 91免费的视频在线播放| 国产va免费精品高清在线| 日韩在线激情视频| 欧美性生交xxxxxdddd| 欧美亚州一区二区三区| 91大神福利视频在线| 亚洲色图欧美制服丝袜另类第一页| 久久视频国产精品免费视频在线| 91热精品视频| 欧美高清视频在线观看| 精品在线欧美视频| 亚洲一品av免费观看| 国产精品第一视频| 亚洲一区二区三区久久|