| 動作 | 函數/旗標 | 行為 |
|---|---|---|
| 捕捉 | signal(sig, handler) sigaction(sig, &act, NULL) | 信號到達時執行自訂處理函數 |
| 忽略 | signal(sig, SIG_IGN) | 信號被丟棄,不影響進程 |
| 預設 | signal(sig, SIG_DFL) | 恢復系統預設動作(通常終止/核心傾印/停止/忽略) |
SIGKILL (9):無條件終止進程,給管理員最後手段SIGSTOP (19):無條件停止進程,配合 SIGCONT 作業控制這兩個信號直接由核心處理,不經過使用者空間處理函數,保證系統可控性。
volatile sig_atomic_t shutdown = 0;
void sig_handler(int sig) {
shutdown = 1; // 只設旗標,不做複雜操作
}
int main() {
struct sigaction sa = {.sa_handler = sig_handler};
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
while (!shutdown) {
// 主迴圈工作
do_work();
// 定期檢查 shutdown,執行清理
}
cleanup();
return 0;
}
問題:在無窮迴圈中用
printf輸出進度會嚴重拖慢效能。解法:主迴圈全速運算,另開終端機送
SIGUSR1觸發狀態輸出。
// 計算進程
volatile sig_atomic_t show_status = 0;
void status_handler(int sig) { show_status = 1; }
int main() {
signal(SIGUSR1, status_handler);
for (long i = 0; ; i++) {
heavy_computation();
if (show_status) {
printf("Progress: %ld iterations\n", i);
show_status = 0;
}
}
}
// 監控終端機:
// $ kill -USR1 # 即時查看進度,不影響運算效能
void sigchld_handler(int sig) {
int saved_errno = errno;
while (waitpid(-1, NULL, WNOHANG) > 0) {}
errno = saved_errno;
}
int main() {
struct sigaction sa = {.sa_handler = sigchld_handler, .sa_flags = SA_RESTART | SA_NOCLDSTOP};
sigaction(SIGCHLD, &sa, NULL);
// fork 子進程...
}
// 參考 setitimer + sigsuspend 模式
// 實現毫秒級精度的非阻塞事件循環
| 規則 | 說明 |
|---|---|
| 只呼叫 async-signal-safe 函數 | man 7 signal-safety 白名單:write、_exit、sigaction、kill 等 |
| 不使用 stdio (printf/malloc/free) | 非重入、鎖競爭、堆損壞 |
| 變數宣告為 volatile sig_atomic_t | 保證原子讀寫、防編譯器優化 |
| 儲存/恢復 errno | 避免中斷系統呼叫後 errno 被覆寫 |
| 處理函數極簡、快速返回 | 避免阻塞其他信號遞送 |
#include <sys/signalfd.h>
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGTERM);
sigprocmask(SIG_BLOCK, &mask, NULL); // 必須先阻塞
int sfd = signalfd(-1, &mask, 0);
// 現在可用 poll/epoll 監聽 sfd,像處理檔案描述符一樣處理信號
// 讀取 signalfd_sinfo 結構取得信號資訊
優點:統一事件迴圈、無重入問題、可傳遞完整信號資訊(pid、uid、code 等)。
信號處理核心在於「簡單可靠」:主迴圈負責複雜邏輯,處理函數只傳遞最小資訊。掌握 sigaction、sigprocmask、sigsuspend 三大核心 API,配合 SA_RESTART、volatile sig_atomic_t、signalfd 現代機制,即能構建健壯的 Linux 系統程式。