若一個程序或子程序可以安全的被并行執(zhí)行,則稱其為可重入(reentrant或re-entrant)的;即,當該子程序正在運行時,可以再次進入并執(zhí)行它。若一個函數是可重入的,則該函數:不能含有靜態(tài)(全局)非常量數據。 不能返回靜態(tài)(全局)非常量數據的地址。 只能處理由調用者提供的數據。 不能依賴于單實例模式資源的鎖。 不能調用不可重入的函數。 多'用戶/對象/進程優(yōu)先級'以及多進程一般會使得對可重入代碼的控制變得復雜。同時,IO代碼通常不是可重入的,因為他們依賴于像磁盤這樣共享的、單獨的資源??芍厝胄允呛瘮稻幊陶Z言的關鍵特性之一。 例子在以下的C語言代碼中,函數f和函數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,則返回的結果取決于執(zhí)行的時間。因此,f不可重入。而g調用了f,所以它也不可重入。稍作修改后,兩個函數都是可重入的:int f(int i){ return i + 2;}int g(int i){ return f(i) + 2;}
10年積累的成都做網站、成都網站建設、成都外貿網站建設經驗,可以快速應對客戶對網站的新想法和需求。提供各種問題對應的解決方案。讓選擇我們的客戶得到更好、更有力的網絡服務。我雖然不認識你,你也不認識我。但先網站制作后付款的網站建設流程,更有大邑縣免費網站建設讓你可以放心的選擇與我們合作。
假如,main()中正在調用A()函數.在此期間,有一中斷,在中斷服務程序中還要調用A().
如果這個A()可以被調用就算是可重入
反之算不可重入.
可重入與不可重入的區(qū)別在這個函數的內容是否會相互沖突...例如A()中有個靜態(tài)變量...就不可以..
可以使用全局變量、靜態(tài)變量。關鍵是不是“只讀”。如果只讀,那怎么用都行。如果有寫的操作,最好避開,實在避不開就要用信號量等機制防止多線程沖突。
另外就是調用的函數要線程安全, thread-safe.具體那些函數線程安全,需要查閱手冊。
一、可重入函數
1)什么是可重入性?
可重入(reentrant)函數可以由多于一個任務并發(fā)使用,而不必擔心數據錯誤。相反, 不可重入(non-reentrant)函數不能由超過一個任務所共享,除非能確保函數的互斥(或者使用信號量,或者在代碼的關鍵部分禁用中斷)??芍厝?函數可以在任意時刻被中斷,稍后再繼續(xù)運行,不會丟失數據。可重入函數要么使用本地變量,要么在使用全局變量時保護自己的數據。
2)可重入函數:
不為連續(xù)的調用持有靜態(tài)數據。
不返回指向靜態(tài)數據的指針;所有數據都由函數的調用者提供。
使用本地數據,或者通過制作全局數據的本地拷貝來保護全局數據。
如果必須訪問全局變量,記住利用互斥信號量來保護全局變量。
絕不調用任何不可重入函數。
3)不可重入函數:
函數中使用了靜態(tài)變量,無論是全局靜態(tài)變量還是局部靜態(tài)變量。
函數返回靜態(tài)變量。
函數中調用了不可重入函數。
函數體內使用了靜態(tài)的數據結構;
函數體內調用了malloc()或者free()函數;
函數體內調用了其他標準I/O函數。
函數是singleton中的成員函數而且使用了不使用線程獨立存儲的成員變量 。
總的來說,如果一個函數在重入條件下使用了未受保護的共享的資源,那么它是不可重入的。