思考:信号中断函数调用中是否被其他信号中断.
信号函数调用中只屏蔽本身信号,不屏蔽其他信号.(屏蔽了本身信号,信号排队,处理函数处理结束后,立即再次处理该信号调用处理函数。其他信号则直接可以中断处理函数。)
怎么保证信号处理函数调用中屏蔽指定信号呢?
sigaction可以指定处理函数调用的屏蔽信号
sigaction在处理信号的时候,接收数据
sigqueue发送信号的时候,可以发送数据
sigaction/sigqueue是signal/kill的增强版本
函数说明:
使用sigaction/sigqueue有两个理由.
稳定
增强功能
intsigaction(
intsig,//被处理信号
conststruct sigaction*action,//处理函数及其参数
structsigaction*oldact//返回原来的处理函数结构体
)
返回:
0:成功
-1:失败
structsigaction
{
void(*sa_handle)(int);
void(*sa_sigaction)(int,siginfo_t*,void*);
sigset_t*mask;//屏蔽信号
intflags;//SA_SIGINFO(使用第二个函数)
void**//保留成员.
}
例子:
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
voidhandle(int s)
{
printf(“信号处理函数正在处理!\n”);
sleep(5);
printf(“信号处理函数处理结束!\n”);
}
voidmain()
{
structsigaction act={0};
act.sa_handle=handle;
sigemptyset(&act.mask);
sigaddset(&act.mask,SIGINT);//信号处理函数屏蔽SIGINT信号
act.flags=0;
sigaction(SIGUSR1,&act,0);
while(1);
}
说明:
当程序运行,并向程序发送了SIGUER信号,程序调用信号处理函数时,我们按下ctrl+c向程序发送SIGINT信号,处理函数不会中断。(处理函数屏蔽了SIGINT信号),当处理函数结束后,程序会立即处理SIGINT信号。
sigqueue函数:
#include<signal.h>
int sigqueue(pid_t pid,
int sig,
const union sigval value//发送信号时发送的数据);
union sigval {
intsival_int;
void * sival_ptr;
};
例子2:sigqueue发送信号并传递数据
//接收信号:
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
void handle(int s,siginfo_t siginfo,void *) //第二个参数是个结构体,该结构体中的成员//si_int存放了传递的int数据,si_ptr 存放了传//递的void*数据.
{
printf(“信号处理函数正在处理!%d\n”,siginfo->si_int);
sleep(5);
printf(“信号处理函数处理结束!\n”);
}
voidmain()
{
structsigaction act={0};
act.sa_sigaction=handle; //要传递数据,要用结构的第二个函数指针
sigemptyset(&act.mask);
sigaddset(&act.mask,SIGINT);//信号处理函数屏蔽SIGINT信号
act.flags=SA_SIGINFO;
sigaction(SIGUER1,&act,0);
while(1);
}
//信号发送
#include<unistd.h>
#include<signal.h>
voidmain()
{
union sigval val;
val.sival_int=9999; //设置传递的数据
sigqueue(pid,SIGUSR1,val);//pid代替上个程序的进程号
}