4

我不是新手,在編程時使用信號。我主要工作在C/C++和Python。 但我很想知道如何在Linux(或Windows)中實際實現信號。在Linux和Windows下實現信號?

如果有任何已註冊的信號需要處理,操作系統是否會檢查信號描述符表中的每條CPU指令?或者是流程管理者/調度員對此負責?

由於信號是異步的,CPU指令在完成之前是否中斷?

+2

編輯帖子並刪除各種大寫。請不要使用此類外部源代碼,因爲它通常在互聯網上被視爲粗魯(「大喊」)。 – Lundin

+0

兩篇文章都非常有幫助:如何信號在Linux中實現(http://cs-pub.bu.edu/fac/richwest/cs591_w1/notes/wk3_pt2.PDF)和[Linux的信號處理模式(HTTP ://www.linuxjournal.com/article/3985) –

回答

6

操作系統絕對不會處理每條指令。沒門。太慢了。

當CPU遇到問題時(如除法0,訪問受限資源或未由物理內存備份的內存位置),它會生成一種特殊的中斷,稱爲異常(不會混淆用C++/Java /等高級語言異常抽象)。

操作系統處理這些異常。如果需要,並且如果可能的話,它可以將異常反射回來源於它的過程。 Windows中所謂的Structured Exception Handling(SEH)就是這種反映。 C信號應該使用相同的機制來實現。

+0

謝謝回答!....我請你,請閱讀http://cs-pub.bu.edu/fac/richwest/cs591_w1/notes/wk3_pt2 .PDF。這裏描述的一些中斷描述符表(IDT)也讀取滑動數字18,表示'CPU執行每條指令後檢查中斷'。這是真的嗎?......對我來說這一切都不清楚。 –

+1

IDT由OS配置,但它是從中取出ISR地址並在那裏傳輸控制權的CPU。而且CPU是第一個檢查中斷的。檢查代碼中的中斷效率非常低。這項工作最好由硬件完成,即CPU。如果您對中斷和異常如何工作感興趣,請閱讀CPU手冊(來自Intel或AMD)。它就在那裏,包括指令之間的中斷「交付」(是的,這是真的)。 –

+0

@Alexye Frunze:我在這裏發佈了一個問題:http://stackoverflow.com/questions/12437648/uninterruptable-program-on-window-linux ...我向你請求請看看並提出一些提示。 –

2

一個進程可以發送信號到另一個進程。進程可以註冊自己的信號處理程序來處理信號。 SIGKILL和SIGSTOP是無法捕獲的兩個信號。

當進程執行信號處理程序,它的塊相同的信號,這意味着,當信號處理程序是在執行時,如果另一相同信號到達時,它不會調用信號處理程序[稱爲阻塞信號],但它使注意信號已經到達[即:待處理信號]。一旦已經運行的信號處理程序被執行,然後處理待處理的信號。如果您不想運行未決信號,那麼您可以忽略該信號。

在上述概念的問題是:

假定以下:用於SIGUSR1 過程A已註冊的信號處理程序。

1) process A gets signal SIGUSR1, and executes signalhandler() 
    2) process A gets SIGUSR1, 
    3) process A gets SIGUSR1, 
    4) process A gets SIGUSR1, 

當步驟(2)發生時,它被設置爲'未決信號'。即;它需要被服務。 並且當步驟(3)發生時,它被忽略,因爲只有一個位 可用於指示每個可用信號的未決信號。

爲了避免這樣的問題,即:如果我們不想丟失信號,那麼我們可以使用 實時信號。 。

2)的信號同步執行,

例如,

 1) process is executing in the middle of signal handler for SIGUSR1, 

    2) Now, it gets another signal SIGUSR2, 

    3) It stops the SIGUSR1, and continues with SIGUSR2, 
     and once it is done with SIGUSR2, then it continues with SIGUSR1. 

3)恕我直言,我記得如果有任何信號到達的過程檢查是:

1) When context switch happens. 

希望這有助於延長。

4

在我所熟悉的(雖然我不明白爲什麼它應該是在其他地方太大的不同),信號傳遞是當過程從內核到用戶模式返回完成的系統。

讓我們首先考慮一個CPU的情況。有三個來源的信號:

  • 過程將信號發送到本身
  • 另一個進程發送信號
  • 中斷處理程序(網絡,磁盤,USB等)導致發送
  • 的信號

在所有這些情況下,目標進程沒有在用戶態運行,但在內核模式。無論是通過系統調用,還是通過上下文切換(因爲除非我們的目標進程未運行,其他進程無法發送信號),或通過中斷處理程序。所以信號傳遞是一個簡單的事情,可以檢查在從內核模式返回到用戶區之前是否有任何信號要傳遞。

在多CPU的情況下,如果目標進程在另一個CPU上運行,它只是一個發送中斷它的運行在CPU的問題。中斷除了強制其他CPU進入內核模式並返回外,其他任何事情都不做任何事情,因此信號處理可以在返回時完成。