2017-09-05 119 views
1

與處理異步信號相比,我試圖找到處理同步信號(SIGSEGV,SIGILL等)的資源。處理同步信號

的典型的信號處理機制(使用kill,例如)調用來自內核的控制轉移到用戶模式信號處理程序。我的理解是,'同步'信號更像是系統調用,因爲控制器會立即傳輸到內核 - 可能是因爲同步信號通常與CPU中斷(內存保護等)相關聯,並且無論如何都會調用內核處理程序。

  1. libc函數是否是'async-signal-unsafe'安全地用於同步信號處理程序?例如,我看到Linux mprotect(2)手冊頁在SIGSEGV處理程序中使用printf。我怎樣才能確定一個函數是否可以在這些情況下使用?

  2. 如何同步信號的一個典型的類Unix內核的處理來自其處理異步信號的有什麼不同?什麼使他們「同步」?

+0

定義的信號是不是異步? –

+0

我不確定。這表示有兩種類型:ftp://ftp.gnu.org/old-gnu/Manuals/glibc-2.2.3/html_chapter/libc_24.html。 –

回答

1

沒有同步和異步信號,但某些信號是異步傳送的,而另一些信號則可傳送同步或異步信號。

交付始終是相同的:如果設置在用戶模式下的信號處理程序被調用。如果未設置,則使用默認行爲(默認行爲是終止進程,除了某些忽略或暫停的信號)。

信號被認爲是如果它們被一些外部原因引發的異步地傳送(例如別人叫kill)。在這種情況下,從過程的角度來看,在發射和傳輸之間有時間:過程可以執行許多事情...

如果檢測到某個信號應該是某個內部運行時間原因,則會同步傳遞信號發射。例如,一個壞的存儲器訪問,其可以提供SIGSEGVSIGBUS,浮點錯誤等被零除其遞送SIGFPE,壞指令(SIGILL)等。在這樣的情況下,它是當前執行的代碼/指令是故障源,然後立即發出信號然後傳遞。在這種情況下,從過程的角度來看,在排放和交付之間什麼也沒有發生。

+0

同步與異步傳送如何影響程序的異步信號安全性?考慮Linux上的man mprotect(2)'中的程序。處理程序在使用異步信號不安全功能時是否不正確? –

+0

是的,在任何**信號處理程序中使用異步信號不安全函數都是不正確的,因爲你永遠不知道信號的發生是否同步。 (1)某些外部事件可能產生SIGFPE(例如),因此您的進程無法知道它是否同步(2)您永遠不知道是否在發生同步傳送時允許對異步不安全功能的調用。所以**不要在信號處理程序中調用異步信號功能**。 –

0

這裏有兩部分。信號的產生和信號的接收。程序通過信號處理程序接收信號。就信號處理器而言,信號的接收總是異步的(即,它不能預測何時將接收到)。

是否產生信號是同步的或異步是另一個問題。來自外部設備的中斷顯然是異步的。來自程序的調用信號將阻止該程序,直到調用返回。在呼叫期間,可以異步地發送信號(即,將其置於接收節目的隊列中)或同步地(即,信號程序的處理程序被調用,並且信號程序/線程被暫停,直到處理程序返回,可能返回一些值。)例如,Windows SendMessage(同步)和PostMessage(異步)

此外:「中斷從外部設備顯然是異步「並暫停當前正在運行的進程,直到處理程序已完成。因此,分段衝突(硬件中斷)暫停當前正在運行的進程(產生硬件信號)。其默認處理將終止該過程。

+0

例如,如果當前進程暫停在SIGSEGV上,執行其他不安全的函數(例如'printf')是否安全?即使被暫停,當前進程是否仍然持有鎖(例如)? –

+0

不允許調用printf(至少行爲是未定義的)。除了有關信號管理(信號掩碼等)的一些事情之外,信號傳遞在全局狀態過程中不做任何事情。所以鎖定鎖,仍然鎖定... –

0

信號處理正如前面提到的評論是同步和異步的。同步意味着進程/線程會執行一些指令,並且這個執行導致了中斷。 forex int * a; printf(「%d」,* a);會導致分段錯誤。 異步: - 客戶端進程和服務器進程示例:-server正在關閉,它將向客戶端發送停止信號。客戶端不會產生任何來自外部進程的中斷。 每當出現同步中斷時,就意味着進程出了問題。建議儘可能不要處理任何庫或複雜語句。假設中斷是由於malloc失敗造成的,比再次使用某些庫函數時會造成問題。更好的方法是在信號處理程序本身中自動重新啓動進程。