
372
|
第十章
當一個信號被引發時,信號處理程序無法知道行程正在執行什麼程式碼;處理程序可能
運作在任何程式碼之間。因此,重點在於,你的行程所安裝的任何信號處理程序,必須
十分小心它所進行的行動以及它所觸及的資料。信號處理程序不應該假定當行程遭中斷
時正在做什麼。尤其是,當它們在修改全域(也就是,共享的)資料時,必須特別謹慎
小心。一般而言,不讓信號處理程序觸及全域資料是一個好主意;然而,下一節我們將
探討一個暫時阻擋信號之遞送的方法,因為此方法讓「信號處理程序」與「行程之其餘
部分」所共享的資料得以被安全地操作。
那麼系統呼叫以及其他程式庫函式,會怎麼樣呢?如果你的行程正在寫入一個檔案或正
在分配記憶體,但是信號處理程序所寫入的是相同的檔案或也在調用
malloc()
,會怎麼
樣呢?或者,當信號被遞送時,如果你的行程正在叫用一個使用靜態緩衝區的函式,例
如
strsignal()
,會怎麼樣呢?
有些函式顯然不可再進入。如果一個程式正在執行一個不可再進入的函式,此時核心引
發了一個信號,接著信號處理程序也在調用相同的不可再進入函式,於是混亂隨之而
來。一個
可再進入函式
(
reentrant function
)就是一個可以在自己內部叫用自己(或是
在相同的行程中並行地從另一個執行緒來叫用自己)的函式。為了能夠可再進入,一個
函式不得操作靜態資料,只能操作分配在堆疊上的資料或是呼叫者所提供的資料,而且
不得調用任何不可再進入函式。
保證可再進入的函式
撰寫一個信號處理程序時,你必須考慮到遭中斷的行程可能位於一個不可再進入函式 ...