重入函式,我們可以理解為函式被多次重複進入。在多工系統環境下會出現這種情況,比如函式b同時被多個任務載入執行,此時函式b就發生了重入。
函式的重入是有條件的,並不是所有的函式都能夠被重入。對於不滿足重入條件的函式進行重入操作,會出現不可預知的錯誤。比如下面的函式就不滿足重入條件,如果對其進行重入操作,會發生不可預知的錯誤。
int a = 0;
func example(int value)
a = value;//(1)
printf("%d", a);
函式對全域性變數a進行操作。如果多個程序同時呼叫了函式expmple(),其中乙個程序剛執行完語句(1),另乙個程序被啟用並呼叫了該函式,此時前面乙個程序呼叫的example函式會被中斷執行。在這種情況下,後乙個程序會對a重新賦了乙個新值。當前面程序被重新喚醒執行時,由於a是全域性變數,函式並不會對其單獨儲存乙個副本,此時就會出現第乙個程序得到的結果跟實際預期結果不想匹配的情況。可以得出的結論是,如果函式操作的有全域性變數,不能直接對其進行重入操作。可以通過關閉中斷或是對操作的變數進行加鎖包含,使得函式可重入。
函式直接操作全域性變數,只是函式不可重入的一種。不可重入函式主要有如下幾種:
(1) 函式不可中斷;
(2)函式對全域性變數不加保護進行操作;
(3)函式中有static型別的變數,對其不加保護進行操作;
(4)函式中呼叫了malloc()和free()函式;(這兩個函式主要是對堆進行操作,需要維護堆的全域性指標,一旦發生重入,會導致不可預知的問題)
對比不可重入函式,如果我們在實際應用中需要用到重入函式,需要注意以下幾點:
(1) 函式可中斷;
(2)函式只有非static的區域性變數操作;
(3)如果函式內部需要static變數,並需要對其進行操作,需要進行加速保護;
(4)操作全域性變數,需要加鎖保護;
(5)函式本身不呼叫不可重入的函式;
今天對重入函式進行了學習,秉著好記性不如爛筆頭的原則,記錄下自己的理解,加深記憶和理解。錯誤和遺漏還望指正,謝謝!!! 後續繼續補充。。。。。。。
可重入函式 可重入核心
可重入函式這一概念早有接觸,但一直未有系統的理解,最近閱讀 apue 訊號一章時,其中講解很到位,故總結如下。訊號作為一種軟中斷,能夠被程序給捕獲,因而也就中斷程序的正常執行,轉而去執行訊號處理程式,最後再返回到原程序繼續正常執行。然而,當程序正在執行 malloc 動態記憶體分配時,訊號產生從而轉...
可重入核心 可重入函式
可重入核心在ulk 深入理解linux核心 中的定義是指若干個程序可以同時在核心態下執行,也就是說多個程序可以在核心態下併發執行核心 在單處理器上,只能實現 微觀上的序列,巨集觀上的並行,即任意時刻,只有乙個進 正執行,其他程序處於阻塞或者等待狀態。這裡的可重入,是指可以多個程序進入核心,並不是重複...
可重入函式
在實時系統的設計中,經常會出現多個任務呼叫同乙個函式的情況。如果這個函式不幸被設計成為不可重入的函式的話,那麼不同任務呼叫這個函式時可能修改其他任務呼叫這個函式的資料,從而導致不可預料的後果。那麼什麼是可重入函式呢?所謂可重入函式是指乙個可以被多個任務呼叫的過程,任務在呼叫時不必擔心資料是否會出錯。...