#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 :
//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 = ;
struct sigaction act;
act.sa_sigaction = catch_signal;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;
//注册SIGINT信号
if (sigaction(SIGINT, &act, NULL) != )
{
printf("sigaction SIGINT failed !\n");
return -;
}
//注册SIGTMIN信号
if (sigaction(SIGRTMIN, &act, NULL) != )
{
printf("sigaction SIGINT failed !\n");
return -;
}
//注册SIGUSR1信号
if (sigaction(SIGUSR1, &act, NULL) != )
{
printf("sigaction SIGINT failed !\n");
return -;
}
//阻塞SIGINT信号和SIGTMIN信号
sigset_t bset;
sigemptyset(&bset);
sigaddset(&bset, SIGINT);
sigaddset(&bset, SIGRTMIN);
//更新进程屏蔽信号状态字
if (sigprocmask(SIG_BLOCK, &bset, NULL) != )
{
printf("sigprocmask() failed !\n");
return -;
}
pid = fork();
if (pid == -)
{
printf("fork() failed ! error message:%s\n", strerror(errno));
return -;
}
if (pid == )
{
int i = , ret = ;
union sigval v1;
union sigval v2;
for (i = ; i < ; i++)
{
v1.sival_int = + i;
ret = sigqueue(getppid(), SIGINT, v1);
if (ret != )
{
printf("发送不可靠信号SIGINT失败! error message:%s\n", strerror(errno));
} else
{
printf("发送不可靠信号SIGINT成功!\n");
}
}
for (i = ; i < ; i++)
{
v2.sival_int = + i;
ret = sigqueue(getppid(), SIGRTMIN, v2);
if (ret != )
{
printf("发送可靠信号SIGTMIN失败! error message:%s\n", strerror(errno));
} else
{
printf("发送可靠信号SIGTMIN成功!\n");
}
}
//发送SIGUSR1信号
if (kill(getppid(), SIGUSR1) != )
{
printf("kill() failed ! error message;%s\n", strerror(errno));
}
exit();
}
//父进程
int res = , status = ;
while ()
{
res = wait(&status);
if (res == -)
{
if (errno == EINTR)
{
continue;
}
break;
}
}
while ()
{
sleep();
}
return ;
}
一:SIGINT是不可靠信号。发送了3次父进程只接收到1次,SIGRTMIN是可靠信号,发送了3次父进程接收到3次信号。
二:对于可靠信号,Linux内核会缓存可靠信号,Linux内核可以缓存8192(各个Linux版本不同)条可靠信号;对于不可靠信号,Linux只能缓存一条不可靠信号。
三:执行命令行: ulimit -a
查看Linux支持的信号性能参数
四:发送信号的数量超过系统上限,将会发送失败