Linux下C/C++程序處理Ctrl+C的例子
遇到一個(gè)場(chǎng)景:程序要讀入文件,而用戶在使用文件時(shí)是用/dev/urandom重定向作為輸入的。(好吧這個(gè)用戶就是測(cè)試我們作業(yè)的助教……)而/dev/urandom顯然是沒有EOF的,只有用Ctrl+C的方法結(jié)束輸入。但是Ctrl+C也會(huì)同時(shí)結(jié)束程序,造成不用刻預(yù)測(cè)的結(jié)果。
因此,程序必須設(shè)法獲知Ctrl+C的發(fā)生并進(jìn)行處理。在Linux下,按下Ctrl+C后,程序會(huì)收到一個(gè)信號(hào)SIGINT;這時(shí)操作系統(tǒng)默認(rèn)會(huì)結(jié)束程序。如果程序不想被默認(rèn)處理,就要設(shè)置對(duì)SIGINT信號(hào)的處理函數(shù)(Handler)。下面是一個(gè)簡(jiǎn)單的例子:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h> // signal functions
volatile sig_atomic_t flag = 0;
static void my_handler(int sig){ // can be called asynchronously
flag = 1; // set flag
}
int main(){
// Register signals
signal(SIGINT, my_handler);
// ^ ^
// 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;
}
(來(lái)源:http://stackoverflow.com/questions/17766550/ctrl-c-interrupt-event-handling-in-linux)
如上面程序所示,一般是在一個(gè)循環(huán)中檢測(cè)一個(gè)標(biāo)志變量flag,而這個(gè)flag只在信號(hào)處理函數(shù)中改變。在這里,my_handler()函數(shù)會(huì)在Ctrl+C按下后被調(diào)用,并設(shè)置flag。注意,由于我們自己設(shè)置了Ctrl+C的處理函數(shù),系統(tǒng)就不會(huì)再按默認(rèn)行為結(jié)束程序了。因此flag的變化會(huì)在循環(huán)中被檢測(cè)到,并作出響應(yīng)。
需要注意的是,網(wǎng)上很多例子中出于演示的方便,在消息處理函數(shù)中使用printf()。這樣是不安全的:設(shè)想程序在正常調(diào)用printf的過(guò)程中收到了Ctrl+C,那么信號(hào)處理函數(shù)就會(huì)再調(diào)用一次printf,這有有造成錯(cuò)誤的可能。有一些函數(shù)經(jīng)過(guò)專門的設(shè)計(jì)可以安全地在信號(hào)處理函數(shù)中使用。
具體的解釋可以參考:Matthew N, Stones R. Beginning Linux Programming[M]. John Wiley & Sons, 2011. 中的 Chapter 11: Processes and Signals。
————————————————
原文鏈接:https://blog.csdn.net/THU_Wm/article/details/41191869
*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。
隔離器相關(guān)文章:隔離器原理