1.[发送信号]函数相关:raise;abort;kill/sigqueue
1.raise--自己给自己发信号:int raise(int sig);
等价于:kill(getpid(),int sig);
2.abort--给自己发送异常终止信号SIGABRT
在哪个进程中调用abort函数,哪个进程就会终止,并发送SIGABRT信号
----------------------------------------------------------
3.kill--发送信号给指定进程:int kill(pid_t pid, int sig);
pid>0:发信号给指定的进程
pid=0:调用kill函数的进程的(同一组的所有进程)
pid<-1:取|pid|发给对应进程组
pid=-1:发送给进程有权限发送的系统中所有进程
4.sigqueue 发送信号(发送信号的同时,将数据也发送给[信号处理函数])
int sigqueue(pid_t pid, int sig, const union sigval value);
1.函数功能:
与kill函数功能几乎一样,都是发送信号
与kill函数不同点是:sigqueue函数发送信号的时候,将数据也发送给[信号处理函数]
2.sigqueue的第三个参数:union sigval value 携带数据
union sigval {
int sival_int;
void *sival_ptr;
};
3.sigqueue的使用规则:***
[1]使用sigqueue函数发送数据给信号处理函数;
[2]注册信号处理函数必须使用sigaction
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
详细过程:
[1]定义sigaction的信号处理函数:其中, siginfo_t* s_t参数用来接收sigqueue函数发来的数据
void handler(int signum, siginfo_t* s_t, void* ptr){
printf(" param = %d\n",s_t->si_int);
}
[2]定义并初始化sigaction的第二个参数变量:struct sigaction类型的变量
struct sigaction act;
sigemptyset(&act.sa_mask); //清空阻塞集合
act.sa_flags=SA_SIGINFO;
act.sa_sigaction=handler; //回调函数
[3]调用sigaction函数注册XXX信号:sigaction(XXX,&act,NULL);
[4]给指定进程,通过sigqueue函数发送[带有数据的XXX信号]
union sigval value;
value.sival_int=24;
sigqueue(getppid(),XXX,value);
2.alarm 实现一次性定时
unsigned int alarm(unsigned int seconds);
[1]执行效果:
程序等待seconds秒后,定时器被触发一次
[2]SIGALARM信号的默认处理方式:终止进程
[3]重点:多次调用alarm函数
1.如果在seconds秒内再次调用了alarm函数设置了新的闹钟,则后面定时器的设置将覆盖前面的设置,
即之前设置的秒数被新的闹钟时间取代;
2.当参数seconds为0时,之前设置的定时器闹钟将被取消,并将剩下的时间返回。
[4]程序案例:
int main(){
int ret=alarm(2);
printf("ret = %d\n",ret);
sleep(10);
printf("--------------"); //此句话不会被打印
}
[gjw@localhost 4-signal]$ ./alarm
ret = 0
闹钟
分析:因为alarm(2)时间到时,产生SIGALRM信号,默认处理:直接杀死进程
3.setitimer 实现周期性定时
int setitimer(int which,
const struct itimerval *restrict value,
struct itimerval *restrict ovalue //设为NULL
);
[1]执行效果:
程序执行restrict value.it_value时间后,第一次触发定时器
之后每间隔restrict value.it_interval时间,周期性地触发定时器
[2]参数:
which
ITIMER_REAL 自然定时法 (real=用户+内核+损耗)SIGALRM
ITIMER_VIRTUAL 只计算[用户]时间 SIGVTALRM
ITIMER_PROF 只计算[用户+内核]时间 SIGPROF
restrict value
struct itimerval {
struct timeval it_interval; //定时器周期性触发的时间
struct timeval it_value; //定时器第一次触发的时间
};
struct timeval { //二者是相加的关系
time_t tv_sec; //秒
suseconds_t tv_usec; //微秒
};
[3]程序案例:
void handler(){
printf("__________________\n");
}
int main(){
signal(SIGALRM,handler);
struct itimerval new_val;
//从当前时刻开始,定时器第一次触发的时间
new_val.it_value.tv_sec=6;
new_val.it_value.tv_usec=0;
//定时器周期性触发的时间
new_val.it_interval.tv_sec=2;
new_val.it_interval.tv_usec=0;
setitimer(ITIMER_REAL,&new_val,NULL);
while(1){
printf("hello,world\n");
sleep(1);
}
}
[gjw@localhost 4-signal]$ ./alarm
hello,world
hello,world
hello,world
hello,world
hello,world
hello,world
__________________
hello,world
hello,world
__________________
hello,world
hello,world
__________________
hello,world