#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/wait.h> #include <signal.h> void catch_signal(int signo, siginfo_t *info, void *p) { switch (signo) { case SIGINT: printf("accept SIGINT! recv data=%d\n",info->si_value.sival_int); break; case 34: //SIGRTMIN似乎不是一個確定的int類型 printf("accept SIGRTMIN! recv data=%d\n",info->si_value.sival_int); break; case SIGUSR1: printf("accept SIGUSR1!\n"); //取消信號阻塞 sigset_t uset; sigemptyset(&uset); sigaddset(&uset, SIGINT); sigaddset(&uset, SIGRTMIN); sigprocmask(SIG_UNBLOCK, &uset, NULL); printf("阻塞解除了!\n"); break; } } int main(int arg, char *args[]) { pid_t pid = 0; struct sigaction act; act.sa_sigaction = catch_signal; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; //注冊SIGINT信號 if (sigaction(SIGINT, &act, NULL) != 0) { printf("sigaction SIGINT failed !\n"); return -1; } //注冊SIGTMIN信號 if (sigaction(SIGRTMIN, &act, NULL) != 0) { printf("sigaction SIGINT failed !\n"); return -1; } //注冊SIGUSR1信號 if (sigaction(SIGUSR1, &act, NULL) != 0) { printf("sigaction SIGINT failed !\n"); return -1; } //阻塞SIGINT信號和SIGTMIN信號 sigset_t bset; sigemptyset(&bset); sigaddset(&bset, SIGINT); sigaddset(&bset, SIGRTMIN); //更新進程屏蔽信號狀態字 if (sigprocmask(SIG_BLOCK, &bset, NULL) != 0) { printf("sigprocmask() failed !\n"); return -1; } pid = fork(); if (pid == -1) { printf("fork() failed ! error message:%s\n", strerror(errno)); return -1; } if (pid == 0) { int i = 0, ret = 0; union sigval v1; union sigval v2; for (i = 0; i < 3; i++) { v1.sival_int = 201 + i; ret = sigqueue(getppid(), SIGINT, v1); if (ret != 0) { printf("發送不可靠信號SIGINT失敗! error message:%s\n", strerror(errno)); } else { printf("發送不可靠信號SIGINT成功!\n"); } } for (i = 0; i < 3; i++) { v2.sival_int = 301 + i; ret = sigqueue(getppid(), SIGRTMIN, v2); if (ret != 0) { printf("發送可靠信號SIGTMIN失敗! error message:%s\n", strerror(errno)); } else { printf("發送可靠信號SIGTMIN成功!\n"); } } //發送SIGUSR1信號 if (kill(getppid(), SIGUSR1) != 0) { printf("kill() failed ! error message;%s\n", strerror(errno)); } exit(0); } //父進程 int res = 0, status = 0; while (1) { res = wait(&status); if (res == -1) { if (errno == EINTR) { continue; } break; } } while (1) { sleep(1); } return 0; }

一:SIGINT是不可靠信號。發送了3次父進程只接收到1次,SIGRTMIN是可靠信號,發送了3次父進程接收到3次信號。
二:對於可靠信號,Linux內核會緩存可靠信號,Linux內核可以緩存8192(各個Linux版本不同)條可靠信號;對於不可靠信號,Linux只能緩存一條不可靠信號。
三:執行命令行: ulimit -a
查看Linux支持的信號性能參數
四:發送信號的數量超過系統上限,將會發送失敗

