愛悠閑 > 可重入函數和不可重入函數

可重入函數和不可重入函數

分類: c++  |  作者: dasgk 相關  |  發布日期 : 2014-06-15  |  熱度 : 227°

可重入函數主要用于多任務環境中,一個可重入的函數簡單來說就是可以被中斷的函數,也就是說,可以在這個函數執行的任何時刻中斷它,轉入OS調度下去執行另外一段代碼,而返回控制時不會出現什么錯誤;而不可重入的函數由于使用了一些系統資源,比如全局變量區,中斷向量表等,所以它如果被中斷的話,可能會出現問題,這類函數是不能運行在多任務環境下的。

可重入函數也可以這樣理解,重入即表示重復進入,首先它意味著這個函數可以被中斷,其次意味著它除了使用自己棧上的變量以外不依賴于任何環境(包括static),這樣的函數就是purecode(純代碼)可重入,可以允許有該函數的多個副本在運行,由于它們使用的是分離的棧,所以不會互相干擾。如果確實需要訪問全局變量(包括static),一定要注意實施互斥手段。可重入函數在并行運行環境中非常重要,但是一般要為訪問全局變量付出一些性能代價。

實時系統的設計中,經常會出現多個任務調用同一個函數的情況。如果這個函數不幸被設計成為不可重入的函數的話,那么不同任務調用這個函數時可能修改其他任務調用這個函數的數據,從而導致不可預料的后果。那么什么是可重入函數呢?所謂可重入函數是指一個可以被多個任務調用的過程,任務在調用時不必擔心數據是否會出錯。不可重入函數在 實時系統設計中被視為不安全函數。
滿足下列條件的函數多數是不可重入的:
1) 函數體內使用了 靜態數據結構
2) 函數體內調用了malloc()或者free()函數;
3) 函數體內調用了標準I/O函數。

如何編寫可重入的函數?
答:在函數體內不訪問那些 全局變量,不使用 靜態 局部變量,堅持只使用局部變量,寫出的函數就將是可重入的。如果必須訪問 全局變量,記住利用互斥 信號量來保護全局變量。
如何將一個不可重入的函數改寫成可重入的函數?
答:把一個不可重入函數變成可重入的唯一方法是用可重入規則來重寫它。其實很簡單,只要遵守了幾條很容易理解的規則,那么寫出來的函數就是可重入的。
1) 不要使用 全局變量。因為別的代碼很可能覆蓋這些 變量值。
2) 在和硬件發生交互的時候,切記執行類似disinterrupt()之類的操作,就是關閉 硬件中斷。完成交互記得打開中斷,在有些系列上,這叫做“進入/退出核心”。
3) 不能調用其它任何不可重入的函數。
4) 謹慎使用 堆棧。最好先在使用前先OS_ENTER_KERNAL。


快乐彩中奖说明