成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

線程安全與可重入函數(shù)

  1. 定義

    創(chuàng)新互聯(lián)專注于企業(yè)營銷型網(wǎng)站建設(shè)、網(wǎng)站重做改版、月湖網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5開發(fā)商城網(wǎng)站建設(shè)、集團公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為月湖等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

    (1).線程安全函數(shù):一般說來,一個函數(shù)被稱為線程安全的,當它被多個并發(fā)線程反復(fù)調(diào)用時,它會一直產(chǎn)生正確的結(jié)果。

    (2).可重入:程序執(zhí)行到某個函數(shù)foo()時,收到信號,于是暫停目前正在執(zhí)行的函數(shù),轉(zhuǎn)到信號處理函數(shù),而這個信號處理函數(shù)的執(zhí)行過程中,又恰恰也會進入到剛剛執(zhí)行的函數(shù)foo(),這樣便發(fā)生了所謂的重入。此時如果foo()能夠正確的運行,而且處理完成后,之前暫停的foo()也能夠正確運行,則說明它是可重入的。

    (3).拓展: 

    1).如果一個函數(shù)中用到了全局或靜態(tài)變量,那么它不是線程安全的,也不是可重入的; 

    2).如果我們對它加以改進,在訪問全局或靜態(tài)變量時使用互斥量或信號量等方式加鎖,則可以使它變成線程安全的,但此時它仍然是不可重入的,因為通常加鎖方式是針對不同線程的訪問,而對同一線程可能出現(xiàn)問題; 

    3).如果將函數(shù)中的全局或靜態(tài)變量去掉,改成函數(shù)參數(shù)等其他形式,則有可能使函數(shù)變成既線程安全,又可重入。

  2. 聯(lián)系

    可重入函數(shù)是線程安全函數(shù)的一個真子集。即可重入函數(shù)是線程安全函數(shù),但是反過來,線程安全函數(shù)未必是可重入函數(shù)。

  3. 區(qū)別

    (1)解決問題:

    a.可重入函數(shù)要解決的問題是,不在函數(shù)內(nèi)部使用靜態(tài)或全局數(shù)據(jù),不返回靜態(tài)或全局數(shù)據(jù),也不調(diào)用不可重入函數(shù)。

    b.線程安全函數(shù)要解決的問題是,多個線程調(diào)用函數(shù)時訪問資源沖突。

    (2)確保措施

  a.確保線程安全的措施是:線程安全函數(shù)不使用共享數(shù)據(jù)(全局、靜態(tài)或堆)或者對共享數(shù)據(jù)實施同步機制保護。

  b.保障可重入的措施:不共享數(shù)據(jù)并且不調(diào)用不可重入函數(shù)。

    (1)不要使用static變量和全局變量,堅持只用局部變量;

    (2)若必須訪問全局變量,利用互斥信號量來保護全局變量;

    (3)獲取得知哪些系統(tǒng)調(diào)用是可重入的,在多任務(wù)處理程序中都使用安全的系統(tǒng)調(diào)用;

    (4)不調(diào)用其它任何不可重入的函數(shù);

    (5)謹慎使用堆棧malloc/new。

  (3)轉(zhuǎn)化

   函數(shù)如果使用靜態(tài)變量,通過加鎖后可以轉(zhuǎn)成線程安全函數(shù),但仍然有可能不是可重入的,比如    strtok。strtok是既不可重入的,也不是線程安全的。加鎖的strtok不是可重入的,但線程安全。而    strtok_r既是可重入的,也是線程安全的。

  (4)在信號處理函數(shù)被調(diào)用

 a. 可重入與線程安全的區(qū)別體現(xiàn)在能否在信號處理函數(shù)中被調(diào)用的問題上,可重入函數(shù)在信號處理函數(shù)中可以被安全調(diào)用,因此同時也是異步信號安全函數(shù);而線程安全函數(shù)不保證可以在信號處理函數(shù)中被安全調(diào)用,如果通過設(shè)置信號阻塞集合等方法保證一個非可重入函數(shù)不被信號中斷,那么它也是異步信號安全函數(shù)。

值得一提的是POSIX 1003.1的Syste m Interface缺省是線程安全的,但不是異步信號安全的。異步信號安全的需要明確表示,比如fork ()和signal()。

 b. 一個非可重入函數(shù)通常(盡管不是所有情況下)由它的外部接口和使用方法即可進行判斷。例如:strtok()是非可重入的,因為它在內(nèi)部存儲了被標記分割的字符串;ctime()函數(shù)也是非可重入的,它返回一個指向靜態(tài)數(shù)據(jù)的指針,而該靜態(tài)數(shù)據(jù)在每次調(diào)用中都被覆蓋重寫。

 c. 線程安全只與函數(shù)的內(nèi)部實現(xiàn)有關(guān),而不影響函數(shù)的外部接口。在C語言中,局部變量是在棧上分配的。因此,任何未使用靜態(tài)數(shù)據(jù)或其他共享資源的函數(shù)都是線程安全的。一個線程安全的函數(shù)通過加鎖的方式來實現(xiàn)多線程對共享數(shù)據(jù)的安全訪問。

4. 函數(shù)的線程不安全與不可重入的原因

(1)任何線程不安全問題的根源都是“共享數(shù)據(jù)”。所以,不使用任何共享數(shù)據(jù)的函數(shù)(即:可重入函  數(shù))肯定是線程安全的。

(2)不可重入函數(shù)的原因在于:

 a. 已知它們使用靜態(tài)數(shù)據(jù)結(jié)構(gòu)
 b. 它們調(diào)用malloc和free.
 因為malloc通常會為所分配的存儲區(qū)維護一個鏈接表,而插入執(zhí)行信號處理函數(shù)的時候,進程可能正  在修改此鏈接表。
 c. 它們是標準IO函數(shù).
 因為標準IO庫的很多實現(xiàn)都使用了全局數(shù)據(jù)結(jié)構(gòu)

(3)線程安全函數(shù)不一定是可重入函數(shù),因為即使有線程有共享數(shù)據(jù),線程被并發(fā)調(diào)用的時候也可以使  其結(jié)果正確--通過同步操作保證正確性。 

共享數(shù)據(jù)可以是:

  1. 函數(shù)把返回結(jié)果放到一個公共的位置

  2. 由調(diào)用者傳入的線程間共享的指針變量或者引用變量

  3. 函數(shù)內(nèi)部本來就會使用的共享靜態(tài)變量

4. 補充

(1)常見的不可重入函數(shù)有:
printf --------引用全局變量stdout
malloc --------全局內(nèi)存分配表
free    --------全局內(nèi)存分配表


(2)不可重入的解決方舉例(printf)

例如,程序正在調(diào)用printf輸出,但是在調(diào)用printf時,出現(xiàn)了信號,對應(yīng)的信號處理函數(shù)也有printf語句,就會導致兩個printf的輸出混雜在一起。
如果是給printf加鎖的話,同樣是上面的情況就會導致死鎖。對于這種情況,采用的方法一般是在特定的區(qū)域屏蔽一定的信號。
屏蔽信號的方法:
1> signal(SIGPIPE, SIG_IGN); //忽略一些信號
2> sigprocmask()
sigprocmask只為單線程定義的
3> pthread_sigmask()
pthread_sigmasks可以在多線程中使用

新聞名稱:線程安全與可重入函數(shù)
文章路徑:http://jinyejixie.com/article24/iejsce.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、響應(yīng)式網(wǎng)站軟件開發(fā)、電子商務(wù)網(wǎng)站導航、搜索引擎優(yōu)化

廣告

聲明:本網(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)

h5響應(yīng)式網(wǎng)站建設(shè)
海门市| 蒙城县| 嘉禾县| 长武县| 吴桥县| 明溪县| 余江县| 黄石市| 临汾市| 金塔县| 利辛县| 东乡族自治县| 新化县| 鄂托克前旗| 永泰县| 永昌县| 道孚县| 新绛县| 潞西市| 普陀区| 河源市| 西青区| 沁阳市| 镇雄县| 汉沽区| 海伦市| 龙南县| 揭西县| 玛纳斯县| 武宁县| 毕节市| 阿坝县| 贵德县| 巴林左旗| 怀远县| 正阳县| 尼木县| 同仁县| 洞口县| 高邮市| 略阳县|