1. 程式人生 > >什麼是可重入函式和不可重入函式?

什麼是可重入函式和不可重入函式?

1.可重入函式
在實時系統的設計中,經常會出現多個任務呼叫同一個函式的情況。如果這個函式不幸被設計成為不可重入的函式的話,那麼不同任務呼叫這個函式時可能修改其他任 務呼叫這個函式的資料,從而導致不可預料的後果。那麼什麼是可重入函式呢?所謂可重入是指一個可以被多個任務呼叫的過程,任務在呼叫時不必擔心資料是否會 出錯。不可重入函式在實時系統設計中被視為不安全函式。
滿足下列條件的函式多數是不可重入的:
(1)函式體內使用了靜態的資料結構;
(2)函式體內呼叫了malloc()或者free()函式;
(3)函式體內呼叫了標準I/O函式。
可重入函式可以被一個以上的任務呼叫,而不必擔心資料被破壞。可重入函式任何時候都可以被中斷,一段時間以後又可以執行,而相應的資料不會丟失。可重入函式或者只使用區域性變數,即儲存在CPU暫存器中或堆疊中;或者使用全域性變數,則要對全域性變數予以保護。說法2:一個可重入的函式簡單來說,就是:可以被中斷的函式。就是說,你可以在這個函式執行的任何時候中斷他的執行,在任務排程下去執行另外一段代 碼而不會出現什麼錯誤。而不可重入的函式由於使用了一些系統資源,比如全域性變數區,中斷向量表等等,所以他如果被中斷的話,可能出現問題,所以這類函式是 不能執行在多工環境下的。
基本上下面的函式是不可重入的
(1)函式體內使用了靜態的資料結構;
(2)函式體內呼叫了malloc()或者free()函式;
(3)函式體內呼叫了標準I/O函式。
把一個不可重入函式變成可重入的唯一方法是用可重入規則來重寫他。
其實很簡單,只要遵守了幾條很容易理解的規則,那麼寫出來的函式就是可重入的。
第一,不要使用全域性變數。因為別的程式碼很可能覆蓋這些變數值。
第二,在和硬體發生互動的時候,切記執行類似disinterrupt()之類的操作,就是關閉硬體中斷。完成互動記得開啟中斷,在有些系列上,這叫做進入/退出核心或者用OS_ENTER_KERNAL/OS_EXIT_KERNAL來描述。//這是臨界區保護
第三,不能呼叫任何不可重入的函式。
第四,謹慎使用堆疊。最好先在使用前先OS_ENTER_KERNAL。
還有一些規則,都是很好理解的,總之,時刻記住一句話:保證中斷是安全的!