发信号raise、abort、kill、killpg / 定时器alarm、setitimer


raise–自己给自己发信号:int raise(int sig);

等价于:kill(getpid(),int sig);

abort–给自己发送异常终止信号SIGABRT

在哪个进程中调用abort()函数,哪个进程就会终止,并发送SIGABRT信号

kill–发送信号给指定进程/进程组:int kill(pid_t pid, int sig);

  • 参数:
    pid>0:发信号给指定的进程
    pid=0:调用kill函数的进程的(同一组的所有进程)
    pid<-1:取|pid|发给对应进程组
    pid=-1:发送给进程有权限发送的系统中所有进程
  • 返回值:
    该调用执行成功时,返回值为0;
    错误时,返回-1,并设置相应 的错误代码errno。

killpg–给进程组发送信号:int killpg(int pgrp, int sig);**

killpg(pgrp, sig)等价于kill(-pgrp, sig);


alarm 实现一次性定时 unsigned int alarm(unsigned int seconds);

功能:alarm安排内核为调用进程在指定的seconds秒后发出一个SIGALRM信号
返回值:如果之前没调用alarm,则返回0;如果之前调用了alarm,则再次调用alarm,返回上一次alarm剩余的时间

#include <unistd.h>
#include <stdio.h>

int main(){          
  int ret=alarm(10);//之前没调用alarm,返回值=0    
  printf("ret = %d\n",ret);
  sleep(2);
  //重新设置到时时间为2s,覆盖之前设置的10s
  ret=alarm(2);  //返回值=8,表示上次设置的alarm剩余的到时时间为8s
  printf("ret = %d\n",ret); 
}  

注意:
1.该闹钟只是一次有效,如果要重复有效,需要重复设置
2.如果在seconds秒内再次调用了alarm函数设置了新的闹钟,则后面定时器的设置将覆盖前面的设置,即之前设置的秒数被新的闹钟时间取代;
3.当参数seconds为0时,之前设置的定时器闹钟将被取消,并将剩下的时间返回。

int main(){          
  int ret=alarm(2);  
  printf("ret = %d\n",ret);  
  sleep(10);         
  printf("--------------"); //此句话不会被打印
}  
[gjw@localhost 4-signal]$ ./alarm 
ret = 0  //立即打印,而不是等待2秒后再打印
闹钟     //等待2秒后,再打印
分析:因为alarm(2)时间到时,产生SIGALRM信号,默认处理:直接杀死进程

setitimer 实现周期性定时

int setitimer(int which, 
	const struct itimerval *restrict value,
	struct itimerval *restrict ovalue  //设为NULL
);
其中第一个参数value的类型struct itimerval介绍:
	struct itimerval {
	    struct timeval it_interval;   //定时器周期性触发的时间
	    struct timeval it_value;  //定时器第一次触发的时间
	};

功能:程序执行restrict value.it_value时间后,第一次触发定时器;之后每间隔restrict value.it_interval时间,周期性地触发定时器

which参数
TIMER_REAL:按实际时间计时,计时到达将给进程发送SIGALRM信号。
ITIMER_VIRTUAL:仅当进程执行时才进行计时。计时到达将发送SIGVTALRM信号给进程。
ITIMER_PROF:当进程执行时和系统为该进程执行动作时都计时。与ITIMER_VIR-TUAL是一对,该定时器经常用来统计进程在用户态和内核态花费的时间。计时到达将发送SIGPROF信号给进程。

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值