複製鏈接
請複製以下鏈接發送給好友

可重入代碼

鎖定
可重入代碼(Reentry code)也叫純代碼(Pure code)是一種允許多個進程同時訪問的代碼。為了使各進程所執行的代碼完全相同,故不允許任何進程對其進行修改。程序在運行過程中可以被打斷,並由開始處再次執行,並且在合理的範圍內(多次重入,而不造成堆棧溢出等其他問題),程序可以在被打斷處繼續執行,且執行結果不受影響。
中文名
可重入代碼
外文名
Reentry code
別    名
純代碼
定    義
一種允許多個進程同時訪問的代碼
要    求
必須保證資源的互不影響的使用
IO代碼
通常不是可重入的

可重入代碼簡介

例:可重入代碼指可被多個函數或程序調用的一段代碼(通常是一個函數),而且它保證在被任何一個函數調用時都以同樣的方式運行,如:
void test()
{
	int i;
    i = 2;
    printf("%d\n", i);
    i++;
    printf("%d\n", i);
}
無論誰調用它結果都一樣,得到
2
3
static int i = 2;
void test()
{
    printf("%d\n", i);
    i++;
    printf("%d\n", i);
}
就不一樣了,對不同的調用結果不一樣:如:
第一次:
2
3
第二次
3
4
第三次
4
5
等等......
該明白了吧

可重入代碼其他不同的解釋

可重入就是,一個函數沒有執行完成,由於外部因素或內部調用,又一次進入該函數執行。可重入代碼,必須保證資源的互不影響的使用,比如全局變量,系統資源等。 在LINUX設備驅動中 關於可重入代碼:
簡單介紹,因為驅動能夠被多個進程調用,互不干擾,這樣驅動必須是可重入的。
可重入最簡單的理解就是任何變量都是局部變量。可重入指函數在運行過程中,被中斷打斷後,待返回時仍然能夠正常運行。這就需要在編寫代碼時注意全局變量和公用資源的使用,同時還需要有編譯器的支持。否則,ucos ii就不能移植到其中了!!

可重入代碼維基百科解釋

若一個程序子程序可以安全的被並行執行,則稱其為可重入reentrant或re-entrant)的;即,當該子程序正在運行時,可以再次進入並執行它。若一個函數是可重入的,則該函數:
不能含有靜態(全局)非常量數據。 不能返回靜態(全局)非常量數據的地址。 只能處理由調用者提供的數據。 不能依賴於單實例模式資源的鎖。 不能調用不可重入的函數。 多'用户/對象/進程優先級'以及多進程一般會使得對可重入代碼的控制變得複雜。同時,IO代碼通常不是可重入的,因為他們依賴於像磁盤這樣共享的、單獨的資源。

可重入代碼與線程安全關係

可重入與線程安全兩個概念都關係到函數處理資源的方式。但是,他們有一定的區別。可重入概念會影響函數的外部接口,而線程安全只關心函數的實現。
  • 大多數情況下,要將不可重入函數改為可重入的,需要修改函數接口,使得所有的數據都通過函數的調用者提供。
  • 要將非線程安全的函數改為線程安全的,則只需要修改函數的實現部分。一般通過加入同步機制以保護共享的資源,使之不會被幾個線程同時訪問。
線程安全與可重入性是兩個不同性質的概念。可重入是在單線程操作系統背景下,重入的函數或者子程序,按照後進先出的線性序依次執行完畢。多線程執行的函數或子程序,各個線程的執行時機是由操作系統調度,不可預期的,但是該函數的每個執行線程都會不時的獲得CPU的時間片,不斷向前推進執行進度。可重入函數未必是線程安全的;線程安全函數未必是可重入的。例如,一個函數打開某個文件並讀入數據。這個函數是可重入的,因為它的多個實例同時執行不會造成衝突;但它不是線程安全的,因為在它讀入文件時可能有別的線程正在修改該文件,為了線程安全必須對文件加“同步鎖”。另一個例子,函數在它的函數體內部訪問共享資源使用了加鎖、解鎖操作,所以它是線程安全的,但是卻不可重入。因為若該函數一個實例運行到已經執行加鎖但未執行解鎖時被停下來,系統又啓動該函數的另外一個實例,則新的實例在加鎖處將轉入等待。如果該函數是一箇中斷處理服務,在中斷處理時又發生新的中斷將導致資源死鎖。

可重入代碼函數

處理資源的方式。但是,他們有一定的區別。可重入概念會影響函數的外部接口,而線程安全只關心函數的實現。
大多數情況下,要將不可重入函數改為可重入的,需要修改函數接口,使得所有的數據都通過函數的調用者提供。 要將非線程安全的函數改為線程安全的,則只需要修改函數的實現部分。一般通過加入同步機制以保護共享的資源,使之不會被幾個進程同時訪問。 因此,相對線程安全來説,可重入性是更基本的特性,它可以保證線程安全:即,所有的可重入函數都是線程安全的,但並非所有的線程安全函數都是可重入的。
可重入性是函數編程語言的關鍵特性之一。