signal.h 定義了進程處理異步信號的標準接口:信號編號宏、處理動作常量、signal() 註冊處理函數、raise() 發送信號、sig_atomic_t 信號安全類型。本文系統整理所有宏、函數原型、語義規則、信號安全編程鐵律、經典示例。
SIG_DFL:默認動作 (終止/棄核/忽略/停止/繼續)。SIG_IGN:忽略信號。SIG_ERR:signal() 失敗返回值。| 宏 | 含義 | 典型來源 | 默認動作 |
|---|---|---|---|
| SIGABRT | 異常終止 | abort() | 終止+棄核 |
| SIGFPE | 浮點/算術異常 | 除零、溢出 | 終止+棄核 |
| SIGILL | 非法指令 | 壞代碼/棧破壞 | 終止+棄核 |
| SIGINT | 終端中斷 | Ctrl+C | 終止 |
| SIGSEGV | 非法內存訪問 | 空指針/越界 | 終止+棄核 |
| SIGTERM | 終止請求 | kill 命令 | 終止 |
POSIX 擴展信號 (SIGCHLD, SIGPIPE, SIGALRM, SIGUSR1/2...) 不在標準 C 範圍內。
sig_atomic_t整數類型 (通常 int),**保證讀寫原子性** (無中斷),用於信號處理函數與主程序共享標志變量。
signal:註冊處理函數void (*signal(int sig, void (*func)(int)))(int);
sig:信號編號 (上表宏)。func:處理函數指針,簽名 void handler(int sig)。可傳 SIG_DFL/SIG_IGN。sig 的處理方式為 func。返回**之前**的處理函數指針 (或 SIG_DFL/IGN/ERR)。SIG_ERR 並置 errno。write/_exit/sigaction 等,**不可調用 printf/malloc/lock**)。volatile sig_atomic_t。SIGFPE` 行為未定義)。raise:向自身發送信號int raise(int sig);
sig 給調用進程/線程。#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void catch_function(int signal) {
printf("Interactive attention signal caught.\n");
// 註意:printf 非信號安全!僅教學演示。生產用 write(STDOUT_FILENO, ...)
}
int main(void) {
if (signal(SIGINT, catch_function) == SIG_ERR) {
fprintf(stderr, "An error occured while setting a signal handler.\n");
exit(EXIT_FAILURE);
}
printf("Raising the interactive attention signal.\n");
if (raise(SIGINT) != 0) {
fprintf(stderr, "Error raising the signal.\n");
exit(EXIT_FAILURE);
}
printf("Exiting.\n");
return 0;
}
輸出:
Raising the interactive attention signal.
Interactive attention signal caught.
Exiting.
volatile sig_atomic_t 標志,或調用 write/_exit/kill/sigprocmask 等安全函數。while (!quit_flag) { ... },在安全點處理複雜邏輯。sigprocmask(SIG_BLOCK, ...) 保護非原子操作。sigsuspend 原子等待。sigaction() (POSIX) 提供更精確控制 (SA_RESTART, SA_SIGINFO, SA_NODEFER),**強烈建議新代碼使用 sigaction**。signal.h 是 C 標準庫中最「危險」的頭文件:**接口簡單但語義陷阱深**。理解 signal() 返回舊處理器、處理函數異步安全約束、sig_atomic_t 原子性保證、raise() 同步發送機制,並**遷移至 sigaction()**,是編寫健壯信號驅動程序的必經之路。