信號是系統用來異步通知一個進程某些事件發生了的機制。從效果上來講,有點像中斷。信號發生時,打斷原有執行過程,進入信號處理函數(若是註冊了的話)或默認處理(忽略或終止程序),結束後恢復原有流程。默認狀況下,信號處理過程當中可能會被其它信號繼續中斷,因此須要考慮各類可能的狀況,好比庫函數重入的問題。信號處理函數執行的上下文是在原有棧幀基礎上繼續的,因此能夠用 setjmp() 和 longjmp()。網絡
typedef void (*__sighandler_t) (int);
__sighandler_t signal (int __sig, __sighandler_t __handler); struct sigaction { union { /* Used if SA_SIGINFO is not set. */ __sighandler_t sa_handler; /* Used if SA_SIGINFO is set. */ void (*sa_sigaction) (int, siginfo_t *, void *); } __sigset_t sa_mask; int sa_flags; }; int sigaction (int __sig, const struct sigaction *__restrict __act, struct sigaction *__restrict __oact);
#define SIG_ERR ((__sighandler_t) -1) /* Error return. */ #define SIG_DFL ((__sighandler_t) 0) /* Default action. */ #define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
int kill (__pid_t __pid, int __sig); int raise (int __sig); unsigned int alarm (unsigned int __seconds); void abort (void);
int sigqueue (__pid_t __pid, int __sig, const union sigval __val);
int sigemptyset (sigset_t *__set); int sigfillset (sigset_t *__set); int sigaddset (sigset_t *__set, int __signo); int sigdelset (sigset_t *__set, int __signo); int sigismember (const sigset_t *__set, int __signo);
// 進程阻塞直到有信號產生 int pause (void); // 阻塞信號 int sigprocmask (int __how /* = SIG_BLOCK or SIG_UNBLOCK or SIG_SETMASK */, const sigset_t *__restrict __set, sigset_t *__restrict __oset); // 得到未決(已產生但未遞送)信號 int sigpending (sigset_t *__set); // 修改信號屏蔽字而後阻塞直到有信號產生 // 與 sigprocmask() + pause() 相比,是原子操做 int sigsuspend (const sigset_t *__set);
#define sigsetjmp(env, savemask) __sigsetjmp (env, savemask) void siglongjmp (sigjmp_buf __env, int __val);
與 setjmp() 和 longjmp() 相比,若是 savemask 不爲 0,使用 siglongjmp() 跳出信號處理函數時會恢復信號屏蔽字。異步
ioctl()、read()、readv()、write()、writev() 針對低速設備(可能會被永遠阻塞,如管道、終端、網絡等)時可能會被信號打斷,若是使用 sigaction() 設置信號處理函數並指定 SA_RESTART 時會從新啓動,不然返回 -1 並設置 errno 爲 EINTR。函數