Signal處理中的函式可重入問題

2021-08-21 12:27:43 字數 1193 閱讀 4955

訊號是軟體層次上模擬的中斷,它是一種非同步通訊的處理機制。訊號的非同步性意味著,應用程式不用等待事件的發生,當訊號發生時應用程式自動陷入到對應的訊號處理函式中。產生訊號的事件對程序而言是隨機出現的。訊號的響應方式有忽略、捕捉、執行預設動作三種。

執行緒安全函式:在c語言中區域性變數是在棧中分配的,任何未使用靜態資料或其他共享資源的函式都是執行緒安全的。使用全域性變數的函式是非執行緒安全的。使用靜態資料或其他共享資源的函式,必須通過加鎖的方式來使函式實現執行緒安全。

執行緒安全的(thread-safe):如果乙個函式在同一時刻可以被多個執行緒安全地呼叫,就稱該函式是執行緒安全的。執行緒安全函式解決多個執行緒呼叫函式時訪問共享資源的衝突問題。

可重入(reentrant)函式可以由多於乙個執行緒併發使用,而不必擔心資料錯誤。可重入函式可以在任意時刻被中斷,稍後再繼續執行,不會丟失資料。可重入性解決函式執行結果的確定性和可重複性。

1)        乙個函式對於多個執行緒是可重入的,則這個函式是執行緒安全的;

2)        乙個函式是執行緒安全的,但並不一定是可重入的,比如使用互斥鎖實現的執行緒安全;

3)        可重入性要強於執行緒安全性。

訊號處理函式中只能呼叫可重入函式,而不能呼叫不可重入函式。程序捕捉到訊號並對其進行處理時,正在執行的正常指令序列就被訊號處理程式臨時中斷,它首先執行該訊號處理函式中的指令。如果從訊號處理程式返回,則繼續執行在捕捉到訊號時正在執行的正常指令序列(這類似於發生硬體中斷時所做的)。但在訊號處理函式中,不能判斷捕捉到訊號時執行緒執行到何處。

訊號處理函式預設情況下是在程序的主線程呼叫的,這種情況下使用不可重入函式,有可能會造成不可預知的錯誤。比如呼叫了malloc函式,為了保證malloc是執行緒安全的,所以內部使用了鎖,根據malloc中鎖的不同處理方式,分別可能會導致以下情況的發生:

1)        如果是普通鎖,在主線程中malloc函式獲取鎖之後被signal中斷,在signal處理函式中繼續呼叫malloc,因為主線程中的malloc已經獲取到了鎖,signal處理函式只能等待鎖釋放,而主線程中的malloc函式正在等待signal處理函式返回後繼續執行,這樣就造成了鎖死;

2)        如果是遞迴鎖,那麼signal處理函式中的malloc函式獲取鎖後進行記憶體分配,因為上次的malloc操作還沒完,可能成會造成記憶體資料混亂。

就定時而言,可不直接使用singal alarm,而使用posix定時器,通過通知執行緒的方式,將定時處理函式放到單獨的執行緒中來處理。

可重入函式 可重入核心

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

可重入核心 可重入函式

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

可重入函式

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