一、sigaction函数
函数声明:
#include <signal.h>
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
函数参数:
- 该函数的第一个参数为信号的值,可以为除SIGKILL及SIGSTOP外的任何一个特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误)
- 第二个参数是指向结构sigaction的一个实例的指针,在结构sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理
- 第三个参数oldact指向的对象用来保存原来对相应信号的处理,可指定oldact为NULL。
sigaction结构体:
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
sigaction中的sa_mask会加入到调用进程的进程屏蔽字。
屏蔽的信号到达后将阻塞直到注册的信号处理函数执行完成。
和sigprocmask指定的掩码不同的是,sigprocmask屏蔽的信号在根本上被阻塞,和信号处理函数有没有执行完成没有关系。
示例:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
void handle(int sig);
__sighandler_t my_signal(int,__sighandler_t);
int main(int argc,char* argv[])
{
//my_signal(SIGINT,handle);
struct sigaction act;
act.sa_handler = handle;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaddset(&act.sa_mask,SIGINT);
if (sigaction(SIGINT,&act,NULL) < 0)
ERR_EXIT("sigaction error");
for(;;)
pause();
return 0;
}
//implement own signal
__sighandler_t my_signal(int sig,__sighandler_t handler)
{
struct sigaction act;
struct sigaction oldact;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(sig,&act,&oldact) < 0)
return SIG_ERR;
return oldact.sa_handler;
}
void handle(int sig)
{
printf("recv a sig=%d\n",sig);
sleep(3);
}
二、sigqueue函数
功能:
新的发送信号系统调用
,
主要是针对实时信号提出的支持信号带有参数
,
与函数
sigaction
()
配合使用
函数声明:
#include <signal.h>
int sigqueue(pid_t pid, int sig, const union sigval value);
函数参数:
进程号,信号,传递的数据
返回值:
成功返回0,失败返回-1
示例:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
void handle(int sig,siginfo_t *,void *);
int main(int argc,char* argv[])
{
//my_signal(SIGINT,handle);
struct sigaction act;
act.sa_sigaction = handle;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGINT,&act,NULL) < 0)
ERR_EXIT("sigaction error");
for(;;)
pause();
return 0;
}
void handle(int sig,siginfo_t *info,void *ctx)
{
printf("recv a sig=%d\n",sig);
printf("recv value=%d\n",info->si_value.sival_int);
sleep(3);
}<span style="font-family: Arial, Helvetica, sans-serif;"></span>
信号发送:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
int main(int argc,char* argv[])
{
if (argc != 2)
{
printf("usage:should 2 para\n");
}
union sigval va;
va.sival_int = 100;
sigqueue(atoi(argv[1]),SIGRTMIN,va);
return 0;
}
通过在短时间内发送多个SIGRTMIN信号,也能证明可靠信号是支持排队的。