若一個程序或子程序可以安全的被并行執(zhí)行,則稱其為可重入(reentrant或re-entrant)的;即,當該子程序正在運行時,可以再次進入并執(zhí)行它。若一個函數(shù)是可重入的,則該函數(shù):不能含有靜態(tài)(全局)非常量數(shù)據(jù)。 不能返回靜態(tài)(全局)非常量數(shù)據(jù)的地址。 只能處理由調(diào)用者提供的數(shù)據(jù)。 不能依賴于單實例模式資源的鎖。 不能調(diào)用不可重入的函數(shù)。 多'用戶/對象/進程優(yōu)先級'以及多進程一般會使得對可重入代碼的控制變得復(fù)雜。同時,IO代碼通常不是可重入的,因為他們依賴于像磁盤這樣共享的、單獨的資源。可重入性是函數(shù)編程語言的關(guān)鍵特性之一。 例子在以下的C語言代碼中,函數(shù)f和函數(shù)g都不是可重入的。int g_var = 1;int f(){ g_var = g_var + 2; return g_var;}int g(){ return f() + 2;}以上代碼中,f使用了全局變量 g_var,所以,如果兩個線程同時執(zhí)行它并訪問g_var,則返回的結(jié)果取決于執(zhí)行的時間。因此,f不可重入。而g調(diào)用了f,所以它也不可重入。稍作修改后,兩個函數(shù)都是可重入的:int f(int i){ return i + 2;}int g(int i){ return f(i) + 2;}
創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供祁門網(wǎng)站建設(shè)、祁門做網(wǎng)站、祁門網(wǎng)站設(shè)計、祁門網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、祁門企業(yè)網(wǎng)站模板建站服務(wù),10多年祁門做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
1.從C語言的語法設(shè)計來說是不支持的,早期的C編譯器未考慮過函數(shù)重載這一功能,所以就會有那么多類似的函數(shù)abs,labs,fabs等等(每種類型都要考慮一個不同的函數(shù)名)。
2.C語言標準就規(guī)定不允許同一作用域中兩個函數(shù)重名。和C語言相關(guān)的域有兩種,一個是給編譯器看得,還有一種是給鏈接器看的,而給編譯器看的這種域主要是關(guān)于
變量的可見范圍,而鏈接器看到的那個是叫文件域,而全局域可能要跨越好幾個文件域,這樣只要兩個同名函數(shù)用static修飾,并且在不同的文件中,就不會
沖突。不過這個實際上已經(jīng)超越了編譯器的范圍,表面看起來兩個函數(shù)同名,但是實際上編譯器為鏈接器產(chǎn)生是指向的同一個函數(shù)地址。
3.函數(shù)重載是一個編譯期行為,主要是通過name mangling來產(chǎn)生不同的匯編符號,讓linker可以正確的link代碼。
4.但是,C語言作為一個具有超強功能的底層語言,是有辦法進行模擬函數(shù)重載的。那就是函數(shù)指針。最簡單的例子就是qsort函數(shù)。這個函數(shù)可以傳遞一個函數(shù)指針變量,通過不同的函數(shù)指針,可以對不同的數(shù)據(jù)類型就行相同的qsort操作,從某種層面來說相當于函數(shù)重載。
假如,main()中正在調(diào)用A()函數(shù).在此期間,有一中斷,在中斷服務(wù)程序中還要調(diào)用A().
如果這個A()可以被調(diào)用就算是可重入
反之算不可重入.
可重入與不可重入的區(qū)別在這個函數(shù)的內(nèi)容是否會相互沖突...例如A()中有個靜態(tài)變量...就不可以..
一、可重入函數(shù)
1)什么是可重入性?
可重入(reentrant)函數(shù)可以由多于一個任務(wù)并發(fā)使用,而不必擔心數(shù)據(jù)錯誤。相反, 不可重入(non-reentrant)函數(shù)不能由超過一個任務(wù)所共享,除非能確保函數(shù)的互斥(或者使用信號量,或者在代碼的關(guān)鍵部分禁用中斷)。可重入 函數(shù)可以在任意時刻被中斷,稍后再繼續(xù)運行,不會丟失數(shù)據(jù)。可重入函數(shù)要么使用本地變量,要么在使用全局變量時保護自己的數(shù)據(jù)。
2)可重入函數(shù):
不為連續(xù)的調(diào)用持有靜態(tài)數(shù)據(jù)。
不返回指向靜態(tài)數(shù)據(jù)的指針;所有數(shù)據(jù)都由函數(shù)的調(diào)用者提供。
使用本地數(shù)據(jù),或者通過制作全局數(shù)據(jù)的本地拷貝來保護全局數(shù)據(jù)。
如果必須訪問全局變量,記住利用互斥信號量來保護全局變量。
絕不調(diào)用任何不可重入函數(shù)。
3)不可重入函數(shù):
函數(shù)中使用了靜態(tài)變量,無論是全局靜態(tài)變量還是局部靜態(tài)變量。
函數(shù)返回靜態(tài)變量。
函數(shù)中調(diào)用了不可重入函數(shù)。
函數(shù)體內(nèi)使用了靜態(tài)的數(shù)據(jù)結(jié)構(gòu);
函數(shù)體內(nèi)調(diào)用了malloc()或者free()函數(shù);
函數(shù)體內(nèi)調(diào)用了其他標準I/O函數(shù)。
函數(shù)是singleton中的成員函數(shù)而且使用了不使用線程獨立存儲的成員變量 。
總的來說,如果一個函數(shù)在重入條件下使用了未受保護的共享的資源,那么它是不可重入的。
如果只讀,那怎么用都行。如果有寫的操作,最好避開,實在避不開就要用信號量等機制防止多線程沖突。
另外就是調(diào)用的函數(shù)要線程安全, thread-safe.具體那些函數(shù)線程安全,需要查閱手冊。
新聞名稱:c語言可以重入函數(shù)嗎,c語言可以重入函數(shù)嗎
網(wǎng)站網(wǎng)址:http://vcdvsql.cn/article12/hecsgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、移動網(wǎng)站建設(shè)、靜態(tài)網(wǎng)站、微信公眾號、用戶體驗、網(wǎng)站內(nèi)鏈
聲明:本網(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)