青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

桃源谷

心靈的旅行

人生就是一場旅行,不在乎旅行的目的地,在乎的是沿途的風景和看風景的心情 !
posts - 32, comments - 42, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

準則6:遵守多線程編程的常識(上)

Posted on 2008-12-29 17:11 lymons 閱讀(2732) 評論(0)  編輯 收藏 引用 所屬分類: C++CUnix/Linux文章翻譯
From 2008精選

UNIX上C++程序設計守則(6)Add star

準則6: 遵守多線程編程的常識


  1. 要準確把握在POSIX標準的函數中,那些函數是非線程安全的,一定不要使用
  2. 要讓自己編寫的函數符合線程安全
    • 在訪問共享數據/變量之前一定要先鎖定
    • 如果使用C++的話,一定要注意函數的同步方法

說明: (1) 要準確把握那些非線程安全的函數,一定不要使用


如果在POSIX平臺上進行多線程編程時,有幾個最基本的知識,也就是所說的“常識”,希望大家一定要嚴格遵守。


...首先、我們要理解“線程安全”的意思。線程安全的函數就是指,“一個能被在多個線程同時調用也不會發生問題的函數”。這樣的函數通常要滿足以下幾個的特質。

  1. 不要操作局部的靜態變量(函數內的static變量)和全局靜態數據(全局變量,函數外的靜態變量)。而且,也不要調用其他的非線程安全的函數
  2. 如果要操作這樣的變量的話,事先必須使用互斥鎖mutex進行同步,否則一定要限制多個線程同時對它的訪問

那么、在POSIX標準的函數里面,也有不滿足上述條件的。由于歷史遺留問題,一些函數的識別標識(signature)的定義沒有考慮到線程安全的問題,所以不管怎么做都不能滿足上述的條件。例如,看看 localtime函數吧。它的定義的識別標識(signature)如下:

struct tm *localtime(const time_t *timer);

localtime 函數是,把一個用整數形式表示的時刻(從1970/1/1到現在為止的秒數)、轉換成一個能讓人容易明白的年月日形式表示出來的tm結構體并返回給調用者的函數。根據規格說明、返回出來的tm結構體是不需要free()掉,也不能釋放的。這個函數典型的實現就像下面的代碼那樣:

struct tm *localtime(const time_t *timer) {
static struct tm t;

/* ... 從timer參數里算出年月日等數值 ... */

t.tm_year = XXX;
/* ...把它們填入到結構體內... */
t.tm_hour = XXX;
t.tm_min = XXX;
t.tm_sec = XXX;

return &t;
}

這個函數如果被像下面那樣使用的話,就會有漏洞:

  1. 在線程A里執行 ta = localtime(x);
  2. 在線程B里執行 tb = localtime(y);
  3. 線程A參照ta結構體里的數據 → 就發現這些數據是一些奇怪的值!

...在函數的說明手冊里對這個問題也沒有做過詳細的說明。關于這個漏洞,在localtime函數即使使用了mutex鎖也不能被回避掉。所以,這個函數定義的識別標識是不行滴。
[譯者lymons注:在多個線程里調用localtime函數之所以有問題的原因是,localtime函數里返回的tm構造體是一個靜態的結構體,所以在線程A里調用localtime函數時,該結構體被賦予正確的值;而在線程A參照這個結構體之前,線程B又調用localtime的話,這個靜態的結構體又被賦予新的一個值。因此在線程A對這個結構體的訪問都是基于一個錯誤的值進行的]


正因為如此,就像上面說過的POSIX規格(SUSv3)里整齊的

asctime, basename, catgets, crypt, ctime, dbm_clearerr, dbm_close, dbm_delete, dbm_error, dbm_fetch, dbm_firstkey, dbm_nextkey, dbm_open, dbm_store, dirname, dlerror, drand48, ecvt, encrypt, endgrent, endpwent, endutxent, fcvt, ftw, gcvt, getc_unlocked, getchar_unlocked, getdate, getenv, getgrent, getgrgid, getgrnam,

(省略)

對于在規格中被定義為非線程安全的函數,應該制定一個避免使用它們的規則出來,并且制作一個能夠自動檢查出是否使用了這些函數的開發環境,應該是比較好的。


反之,在這里沒有被登載的POSIX標準函數都被假定為 "shall be thread-safe" 的、所以在實際的使用中可以認為在多線程環境里是沒有問題的(而且在使用的平臺上沒有特別地說明它是非線程安全的話)。


另外,有幾個非線程安全的函數,都準備了一個備用的線程安全版本的函數(僅僅是變更了函數的識別標識)。像這些函數為了與原版進行區別都在其函數名后面添加了 _r 這個后綴*1。例如,asctime函數就有線程安全版本的函數asctime_r。在規格說明中是否定義了備用函數,可以試著點擊剛才的那個網頁里面的函數名就可以看到。點擊 rand函數就可以看到,

[TSF] int rand_r(unsigned *seed);

用[TSF]這樣的文字標記出來的函數吧。這就是備用函數。在一覽中沒有記載出來的函數(備注: 稍微有點兒出入。請參照這里)、據我所知還有下面的備用函數。

asctime_r, ctime_r, getgrgid_r, getgrnam_r, getpwnam_r, getpwuid_r, gmtime_r, localtime_r, rand_r, readdir_r, strerror_r, strtok_r

還有,在規格以外,還準備了很多的下面那樣的函數。

gethostbyname_r, gethostbyname2_r

在最近的操作系統中、也使用 getaddrinfo API函數來解決IPv6名字對應的問題。gethostbyname系列的API都是比較陳舊的函數了、所以使用前面的函數還是比較好吧*2。根據規格SUSv3,getaddrinfo也是線程安全的:

The freeaddrinfo() and getaddrinfo() functions shall be thread-safe.

在多線程編程中,不要使用非線程安全的函數,而他們的備用函數可以放心地積極的去使用。


后續

*1:在C言語里函數不能重載,所以只能添加一個新的函數

*2:跟網絡有關的API哪些是新的哪些是舊的,可以參考 IPv6網絡編程 (network technology series) 這本好書

我的個人簡歷第一頁 我的個人簡歷第二頁
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            9i看片成人免费高清| 欧美激情第9页| 亚洲精品一区二区三区蜜桃久| 一区二区激情小说| 亚洲人成网站色ww在线| 亚洲欧美日韩久久精品| 一本不卡影院| 老**午夜毛片一区二区三区| 性欧美xxxx大乳国产app| 欧美黄色精品| 欧美激情1区2区3区| 国产亚洲欧美另类中文 | 亚洲综合国产激情另类一区| 美女黄毛**国产精品啪啪| 久久免费国产| 国产欧美亚洲日本| 亚洲一区影院| 午夜精品久久久久久久99黑人| 欧美精品一区二区在线观看| 亚洲国产精品999| 黄色成人av网| 久久爱www久久做| 欧美一级夜夜爽| 国产精品女人久久久久久| 亚洲最新视频在线| 亚洲视频网在线直播| 欧美日韩午夜在线视频| 亚洲最新视频在线| 亚洲免费视频中文字幕| 国产精品激情电影| 亚洲一区高清| 久久精品99久久香蕉国产色戒| 国产精品一级久久久| 亚洲欧美日韩人成在线播放| 欧美亚洲一区三区| 国产揄拍国内精品对白| 久久精品国产亚洲高清剧情介绍| 久久精品一本久久99精品| 国内精品久久久久影院色| 欧美在线地址| 亚洲第一综合天堂另类专| 亚洲剧情一区二区| 欧美日韩一区二区在线观看视频| 一二三区精品| 欧美伊人久久| 在线播放一区| 欧美日韩精选| 亚洲伊人网站| 蜜桃av噜噜一区| 亚洲精品免费网站| 国产精品久久久久77777| 篠田优中文在线播放第一区| 免费观看成人网| 一区二区精品在线| 国产日韩精品一区观看| 狼人天天伊人久久| 一本色道久久| 久久综合久久久久88| 亚洲精品小视频在线观看| 国产精品久久久久久久久免费桃花| 午夜精品一区二区三区电影天堂| 免费影视亚洲| 亚洲欧美不卡| 亚洲电影免费观看高清| 欧美日在线观看| 久久久免费精品| 亚洲深夜福利网站| 欧美成人自拍视频| 亚洲尤物精选| 最新国产成人在线观看| 国产精品一区在线观看你懂的| 久久综合伊人77777麻豆| 中文欧美在线视频| 欧美激情在线有限公司| 欧美一区二区三区日韩| 日韩亚洲欧美综合| 国内精品久久久久久久影视麻豆| 欧美日韩国产一区精品一区| 久久九九精品99国产精品| 亚洲图片欧美午夜| 最新国产成人在线观看| 久久在线视频| 亚洲欧美视频| a4yy欧美一区二区三区| 在线免费日韩片| 国产精品一区2区| 欧美日韩成人在线| 麻豆亚洲精品| 久久亚洲不卡| 久久精品日韩一区二区三区| 亚洲一区二区成人| 亚洲精品影视在线观看| 亚洲福利在线视频| 久久在线视频在线| 欧美在线观看视频| 欧美亚洲网站| 午夜日韩在线观看| 亚洲欧美在线一区二区| 亚洲在线免费| 亚洲视频一二| 国产精品99久久久久久久久| 亚洲欧洲视频在线| 亚洲人成人一区二区在线观看| 激情综合网址| 在线观看亚洲一区| 精品动漫一区| 精品福利电影| 在线欧美日韩精品| 亚洲国产精品一区制服丝袜 | 国产精品男女猛烈高潮激情| 欧美日韩国产页| 欧美日韩成人综合| 欧美日韩一区二区在线观看视频| 欧美日本亚洲| 国产精品久久7| 国产精品综合不卡av| 国产欧美日韩综合一区在线观看 | 久久午夜电影| 久久久久亚洲综合| 久久在线免费观看| 欧美xx69| 亚洲日本va午夜在线电影| 亚洲精品美女在线| 一区二区三区日韩欧美| 亚洲欧美国产不卡| 欧美专区在线| 男人插女人欧美| 欧美人妖另类| 国产欧美亚洲视频| 尤物精品在线| 日韩一二三区视频| 亚洲一区免费网站| 久久九九全国免费精品观看| 蜜臀久久99精品久久久久久9 | 亚洲经典自拍| 亚洲午夜久久久| 欧美亚洲免费电影| 免费成人性网站| 欧美精品一区三区| 国产九九精品| 亚洲精品欧洲| 欧美在线啊v一区| 欧美大片第1页| 亚洲视频在线二区| 久久视频精品在线| 国产精品高潮在线| 亚洲第一区在线观看| 亚洲一区二区精品| 久久一区亚洲| 一本色道久久88精品综合| 羞羞色国产精品| 欧美日韩高清在线| 激情五月综合色婷婷一区二区| 亚洲精品乱码久久久久久蜜桃91| 先锋影音一区二区三区| 亚洲第一区在线观看| 亚洲免费在线精品一区| 欧美成人xxx| 国产一区日韩二区欧美三区| 一本色道久久88综合亚洲精品ⅰ| 久久久综合网站| 亚洲丝袜av一区| 欧美精品一区二区三区蜜桃 | 欧美日韩日本视频| 悠悠资源网亚洲青| 午夜精品福利一区二区三区av| 欧美高清不卡在线| 久久成人在线| 国产精品欧美日韩一区| 亚洲精品国产精品乱码不99| 久久久久在线| 亚洲欧美日韩成人高清在线一区| 欧美另类高清视频在线| 亚洲电影免费观看高清完整版在线观看 | 日韩一级黄色av| 免费不卡视频| 一区二区三区在线看| 欧美一区二区高清在线观看| 亚洲伦理在线观看| 欧美高清视频一区二区三区在线观看| 国产日本欧美一区二区三区在线| 亚洲视频免费在线| 日韩一级裸体免费视频| 欧美激情视频免费观看| 亚洲区在线播放| 欧美激情一区二区三区四区| 久久精品国产免费观看| 国产自产精品| 久久亚裔精品欧美| 久久国产精品免费一区| 国产亚洲欧美日韩日本| 欧美在线视频导航| 欧美在线free| 国内自拍亚洲| 老色鬼精品视频在线观看播放| 香港久久久电影| 狠狠爱成人网| 欧美国产激情二区三区| 欧美精品首页| 亚洲一区二区在线播放|