C/C++ 捕捉 ctrl+c 事件的 2 種方法

本篇 ShengYu 介紹 C/C++ 捕捉 ctrl+c 事件的 2 種方法,第 1 種是 signal 方式,第 2 種是 sigaction 方式,

signal 方式

這個方式適用於大多數系統,這是標準 C 函式庫就有支援,我們這邊要捕捉的是 ctrl+c 的事件,對應的是 SIGINT signal,
所以我們需要的是使用 signal() 函式註冊 SIGINT 這個事件發生時,要來執行我們預先定義好的 signal_handler 函式,
注意這邊的 sig_handler 是有註冊成功的 signal 才會進來,例如我這邊只有註冊 SIGINT,所以 SIGINT 這個 signal 會進來 sig_handler,其他的像 SIGABRT、SIGSEGV、SIGILL、SIGTERM 等等沒註冊的自然不會進 sig_handler,

cpp-signal-sigint.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// g++ cpp-signal-sigint.cpp -o a.out -std=c++11
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <thread> // for std::this_thread::sleep_for

void signal_handler(int signum) {
printf("signal_handler: caught signal %d\n", signum);
if (signum == SIGINT) {
printf("SIGINT\n");
exit(1);
}
}

int main() {
if (signal(SIGINT, signal_handler) == SIG_ERR) {
printf("Failed to caught signal\n");
}

while(1) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}

return 0;
}

輸出如下,按下 Ctrl+C 後會看到 ^C 字樣,接著就進入到我們定義的 signal_handler 函式裡,然後判斷是 SIGINT 就離開程式,

1
2
^Csignal_handler: caught signal 2
SIGINT

sigaction 方式

這邊我們示範另外一種 sigaction 的方式,比上述的 signal 還強大,能處理更複雜的功能,不過我們這邊只是要用來攔住 ctrl+c 的事件而已,用法如下,
事先需要先初始化好 sigaction 結構的變數,再用 sigaction() 來註冊 SIGINT 的事件,這個事件發生時就會來執行我們預先定義好的 signal_handler 函式,

cpp-sigaction-sigint.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// g++ cpp-sigaction-sigint.cpp -o a.out -std=c++11
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <thread> // for std::this_thread::sleep_for

void signal_handler(int signum) {
printf("signal_handler: caught signal %d\n", signum);
if (signum == SIGINT) {
printf("SIGINT\n");
exit(1);
}
}

int main() {
struct sigaction sa;
sa.sa_handler = signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;

if (sigaction(SIGINT, &sa, NULL) == -1) {
printf("Failed to caught signal\n");
}

while(1) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}

return 0;
}

效果是跟前一個方法一樣。

其它參考
c++ - How can I catch a ctrl+c event? - Stack Overflow
https://stackoverflow.com/questions/1641182/how-can-i-catch-a-ctrl+c-event

其它相關文章推薦
Python 捕捉 ctrl+c 事件的方法
C/C++ 新手入門教學懶人包