2013-07-20 39 views
18

我正在開發一個使用C++並使用Linux GNU C編譯器編譯的應用程序。但是,我想調用一個函數,因爲用戶使用中斷腳本時使用CtrlC鍵。我該怎麼辦?任何答案將不勝感激。在Linux中Ctrl + C中斷事件處理

+0

你不必[定義信號處理程序(http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC351)爲SIGINT,得到[這一點的想法代碼(HTTP://計算器。com/questions/17705842/is-there-a-way-make-my-program-work-with-less-code) –

+8

這與使用的編譯器有什麼關係? – 2013-07-20 20:52:42

+3

@mozcelikors沒有「GCC認可的圖書館」之類的東西。如果有標準C編寫的庫,任何理智的C編譯器都應該能夠編譯它。 – 2013-07-20 20:55:23

回答

42

當您按下CTR + C,操作系統發送signal的過程。有很多信號,其中之一是SIGINT。 SIGINT(「程序中斷」)是終止信號之一。

有幾個多種終止信號,而是SIGINT有趣的是,它可以通過你的程序進行處理(捕獲)。 SIGINT的默認操作是程序終止。也就是說,如果你的程序沒有專門處理這個信號,當你按Ctr + C你的程序將作爲默認動作終止。

要更改信號的默認操作,您必須註冊要捕獲的信號。要註冊在C程序(至少在POSIX系統)的信號有兩個功能

  1. signal(int signum, sighandler_t handler);
  2. sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

這些函數需要標頭signal.h包含在您的C代碼中。我在下面提供了一個簡單的signal函數示例和註釋。

#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> // our new library 
volatile sig_atomic_t flag = 0; 
void my_function(int sig){ // can be called asynchronously 
    flag = 1; // set flag 
} 

int main(){ 
    // Register signals 
    signal(SIGINT, my_function); 
    // ^  ^
    // Which-Signal |-- which user defined function registered 
    while(1) 
    if(flag){ // my action when signal set it 1 
     printf("\n Signal caught!\n"); 
     printf("\n default action it not termination!\n"); 
     flag = 0; 
    }  
    return 0; 
} 

注意:您應該只調用信號處理程序safe/authorized functions。例如avoid calling printf in signal handler

您可以使用gcc編譯此代碼並從shell執行它。代碼中有一個無限循環,它會一直運行,直到您通過按Ctr + C發送SIGINT信號。

+1

你可以留下評論給你的疑惑,我只是試圖給你一個快速的開始點。我相信,如果您有更多的努力,您會詳細探索這些事情。 –

+1

感謝您的好評和答覆,這很好。 – mozcelikors

+0

我很確定這個過程是發送一個信號,而不是一個單一的。 :-) – celtschk

9

打字按CtrlÇ通常會導致外殼送SIGINT到您的程序。爲該信號添加處理程序(通過signal(2)sigaction(2)),並且您可以按照自己喜歡的方式操作CtrlC被按下。或者,如果您只關心在程序退出之前進行清理,則通過atexit(3)設置退出處理程序可能更合適。

3

您可以使用信號宏。

下面是如何處理它的一個例子:

#include <signal.h> 
#include <stdio.h> 
void sigint(int a) 
{ 
    printf("^C caught\n"); 
} 
int main() 
{ 
    signal(SIGINT, sigint); 
    for (;;) {} 
} 

輸出示例:

Ethans-MacBook-Pro:~ phyrrus9$ ./a.out 
^C^C caught 
^C^C caught 
^C^C caught 
^C^C caught 
^C^C caught 
+7

避免在信號處理程序中使用printf –

+0

這樣簡單。我用它來關閉i2c連接,因此printf將被替換爲連接查殺功能。非常感謝。 – mozcelikors