可/不可重入函数
一個函數(shù)在被調(diào)用執(zhí)行期間(尚未調(diào)用結(jié)束),由于某種時序(遞歸或者處理信號捕捉時等情況)又被重復(fù)調(diào)用,稱之為“重入”。根據(jù)函數(shù)實(shí)現(xiàn)的方法可分為“可重入函數(shù)”和“不可重入函數(shù)”兩種。看如下程序。
可以看出在進(jìn)程主控程序的insert函數(shù)未執(zhí)行完時(在執(zhí)行完p->next=head時,收到一個信號,需要立即去處理信號),馬上內(nèi)核接著調(diào)用了insert函數(shù)來將node2節(jié)點(diǎn)插入鏈表。預(yù)期結(jié)果應(yīng)該是node1與node2兩個節(jié)點(diǎn)都插入鏈表中形成一個單鏈表,但由于insert函數(shù)中的變量head為全局變量,因此函數(shù)的兩次調(diào)用都可以對同一個變量修改,其修改的順序不同會造成結(jié)果不同,最終導(dǎo)致達(dá)不到預(yù)期的結(jié)果。因此,insert函數(shù)是不可重入函數(shù),重入調(diào)用,會導(dǎo)致意外結(jié)果呈現(xiàn)。究其原因,是該函數(shù)內(nèi)部實(shí)現(xiàn)使用了全局變量。
可重入函數(shù)是指重入不會產(chǎn)生異常結(jié)果的函數(shù),即允許在函數(shù)執(zhí)行期間再次調(diào)用該函數(shù)。
注意事項(xiàng):
1.對于可重入函數(shù),函數(shù)內(nèi)部不能含有全局變量和static變量,因?yàn)檫@種變量可以被函數(shù)的多次重入調(diào)用共同控制,其最終的結(jié)果依賴于它們的執(zhí)行順序;
2.可重入函數(shù)的定義中也不能使用malloc和free函數(shù),因?yàn)閙alloc和free函數(shù)的底層實(shí)現(xiàn)是用全局指針完成的;
3.信號捕捉函數(shù)應(yīng)該設(shè)計成可重入函數(shù);
4.信號處理程序可以調(diào)用的可重入函數(shù)可參閱man 7 signal
5.沒有包含在上述列表中的函數(shù)大多是不可重入的,其原因?yàn)?#xff1a;使用靜態(tài)數(shù)據(jù)結(jié)構(gòu);調(diào)用了malloc或free;是標(biāo)準(zhǔn)I/O函數(shù)。
malloc、free系統(tǒng)調(diào)用是不可重入函數(shù),底層實(shí)現(xiàn)是用全局指針完成的。strtok是不可重入函數(shù),其內(nèi)部含有一個static變量;strtok_r為可重入函數(shù),其將strtok函數(shù)的static變量變?yōu)橐粋€非靜態(tài)局部變量,作為該函數(shù)的第三個參數(shù)。
總結(jié)
- 上一篇: 全局变量的异步I/O问题
- 下一篇: 信号传参