可重入函式

2021-08-18 11:37:05 字數 1012 閱讀 5661

如上圖所示,main函式呼叫insert函式向乙個鍊錶head中插入節點node1,插入操作分為兩步,剛做完第一步時,因為硬體中斷使程序切換到核心,再次回使用者態之前檢查到有訊號待處理,於是切換到sighandler函式,sighandler也呼叫insert函式向同乙個鍊錶head中插入節點弄得,插入操作的兩步都做完之後,從sighandler返回核心態,再次回到使用者態就從main函式呼叫的insert函式中繼續向下執行,先前做第一步之後被打斷,現在繼續做完第二步。結果是,main函式和sighandler先後向鍊錶中插入兩個節點,而最後只有乙個節點真正插入到鍊錶中。

向上例這樣insert函式被不同的控制流程呼叫,有可能在第一次呼叫還未返回時就再次進入該函式,這就稱為重入。

insert函式訪問乙個全域性鍊錶,有可能因為重入而造成錯亂,像這樣的函式稱為不可重入函式。

如果乙個函式只訪問自己的區域性變數或引數,則成為可重入函式。

1.呼叫了malloc或free,因為malloc也是用全域性鍊錶來管理堆的。

2.呼叫了標準i/o庫函式。標準i/o庫函式的很多實現都以不可重入的方式使用全域性資料結構。

在c語言學習時,我們就學習過volatile,知道其作用是保持記憶體的可見性。

在上面這個例子中,main和sighandler都呼叫insert函式則有可能出現鍊錶的錯亂,其根本原因在於,對全域性鍊錶的插入操作要分兩步完成,不是乙個原子操作,假如這兩步操作必定會一起做完,中間不可能被打斷,就不會出現錯亂了。

對於程式中存在多個執行流程訪問同一全域性變數的情況,volatile限定符是必要的。

此外,雖然程式只有單一的執行流程,但是變數屬於以下情況之一的,也需要volatile限定:

1.變數的記憶體單元中的資料不需要寫操作就可以自己發生變化,每次讀上來的值都可能不一樣;

2.即使多次向變數的記憶體單元中寫資料,只寫不讀,也並不是在做無用功,而是有特殊意義的。對映到記憶體位址空間的硬體暫存器具有這樣的特性。

可重入函式 可重入核心

可重入函式這一概念早有接觸,但一直未有系統的理解,最近閱讀 apue 訊號一章時,其中講解很到位,故總結如下。訊號作為一種軟中斷,能夠被程序給捕獲,因而也就中斷程序的正常執行,轉而去執行訊號處理程式,最後再返回到原程序繼續正常執行。然而,當程序正在執行 malloc 動態記憶體分配時,訊號產生從而轉...

可重入核心 可重入函式

可重入核心在ulk 深入理解linux核心 中的定義是指若干個程序可以同時在核心態下執行,也就是說多個程序可以在核心態下併發執行核心 在單處理器上,只能實現 微觀上的序列,巨集觀上的並行,即任意時刻,只有乙個進 正執行,其他程序處於阻塞或者等待狀態。這裡的可重入,是指可以多個程序進入核心,並不是重複...

可重入函式

在實時系統的設計中,經常會出現多個任務呼叫同乙個函式的情況。如果這個函式不幸被設計成為不可重入的函式的話,那麼不同任務呼叫這個函式時可能修改其他任務呼叫這個函式的資料,從而導致不可預料的後果。那麼什麼是可重入函式呢?所謂可重入函式是指乙個可以被多個任務呼叫的過程,任務在呼叫時不必擔心資料是否會出錯。...