一、可重入函數(shù)
可重入函數(shù)主要用于多任務(wù)環(huán)境中,一個可重入的函數(shù)簡單來說就是可以被中斷的函數(shù),也就是說,可以在這個函數(shù)執(zhí)行的任何時(shí)刻中斷它,轉(zhuǎn)入OS調(diào)度下去執(zhí)行另外一段代碼,而返回控制時(shí)不會出現(xiàn)什么錯誤;,局部變量可重入函數(shù); 不可重入的函數(shù)由于使用了一些系統(tǒng)資源,比如全局變量區(qū),中斷向量表等,所以它如果被中斷的話,可能會出現(xiàn)問題,這類函數(shù)是不能運(yùn)行在多任務(wù)環(huán)境下的。
如上圖:
main函數(shù)調(diào)用insert函數(shù)向一個鏈表head中插入節(jié)點(diǎn)node1,插入操作分為兩步,剛做完第一步的 時(shí)候,因?yàn)橛布袛嗍惯M(jìn)程切換到內(nèi)核,再次回用戶態(tài)之前檢查到有信號待處理,于是切換到sighandler函數(shù),sighandler也調(diào)用insert函數(shù)向同一個鏈表head中插入節(jié)點(diǎn)node2,插入操作的兩步都做完之后從ighandler返回內(nèi)核態(tài),再次回到用戶態(tài)就從main函數(shù)調(diào)用的insert函數(shù)中繼續(xù)往下執(zhí)行,先前做第一步之后被打斷,現(xiàn)在繼續(xù)做完第二步。結(jié)果是,main函數(shù)和sighandler先后向鏈表中插入兩個節(jié)點(diǎn),而最后只有一個節(jié)點(diǎn)真正插入鏈表中了。這就出現(xiàn)了泄漏。像上例這樣,insert函數(shù)被不同的控制流程調(diào)用,有可能在第一次調(diào)用還沒返回時(shí)就再次進(jìn)入該函數(shù),這稱為重入,insert函數(shù)訪問一個全局鏈表,有可能因?yàn)橹厝攵斐慑e亂,像這樣的函數(shù)稱為不可重入函數(shù),反之,如果一個函數(shù)只訪問自己的局部變量或參數(shù),則稱為可重入(Reentrant) 函數(shù)
1、 如果一個函數(shù)符合以下條件之一則是不可重入的
①、調(diào)用了malloc或free,因?yàn)閙alloc也是用全局鏈表來管理堆的。
②、調(diào)用了標(biāo)準(zhǔn)I/O庫函數(shù)。標(biāo)準(zhǔn)I/O庫的很多實(shí)現(xiàn)都以不可重入的方式使用全局?jǐn)?shù)據(jù)結(jié)構(gòu)。
二、線程安全
如果代碼所在的進(jìn)程中有多個線程在同時(shí)運(yùn)行,而這些線程可能會同時(shí)運(yùn)行這段代碼。如果每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,就是線程安全的。或者說:一個類或者程序所提供的接口對于線程來說是原子操作或者多個線程之間的切換不會導(dǎo)致該接口的執(zhí)行結(jié)果存在二義性,
線程安全問題都是由全局變量及靜態(tài)變量引起的。若每個線程中對全局變量、靜態(tài)變量只有讀操作,而無寫操作,一般來說,這個全局變量是線程安全的;若有多個線程同時(shí)執(zhí)行寫操作,一般都需要考慮線程同步,否則的話就可能影響線程安全。產(chǎn)生線程安全的本質(zhì)在于:線程共享和執(zhí)行流發(fā)生了干擾。要確保線程安全,線程在對共享變量進(jìn)行訪問時(shí)必須以加鎖的方式。
比如一個 ArrayList 類,在添加一個元素的時(shí)候,它可能會有兩步來完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。
在單線程運(yùn)行的情況下,如果 Size = 0,添加一個元素后,此元素在位置 0,而且 Size=1;而如果是在多線程情況下,比如有兩個線程,線程 A 先將元素存放在位置 0。但是此時(shí) CPU 調(diào)度線程A暫停,線程 B 得到運(yùn)行的機(jī)會。線程B也向此 ArrayList 添加元素,因?yàn)榇藭r(shí) Size 仍然等于 0 (注意,我們假設(shè)的是添加一個元素是要兩個步驟哦,而線程A僅僅完成了步驟1),所以線程B也將元素存放在位置0。然后線程A和線程B都繼續(xù)運(yùn)行,都增加 Size 的值。那好,我們來看看 ArrayList 的情況,元素實(shí)際上只有一個,存放在位置 0,而 Size 卻等于 2。這就是“線程不安全”了。
三、可重入函數(shù)與線程安全的聯(lián)系與區(qū)別
1、可重入函數(shù)一定是線程安全的,單線程安全不一定是可重入的
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
文章題目:可重入函數(shù)和線程安全-創(chuàng)新互聯(lián)
網(wǎng)頁路徑:http://www.chinadenli.net/article18/dsoigp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、軟件開發(fā)、用戶體驗(yàn)、App設(shè)計(jì)、品牌網(wǎng)站設(shè)計(jì)、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容