信号基础知识

信号的机制

        进程A给进程B发送信号,进程B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要暂停运行,去处理信号。处理完毕以后再继续执行,与硬件中断类似(软中断),每个进程收到的所有信号,都是由内湖负责发送的

 信号的处理方式

  • 执行默认动作
  • 忽略信号(丢弃不处理)
  • 捕捉信号(调用用户的自定义的处理函数)

信号相关函数  

signal函数:

  • 作用:注册信号捕捉(处理)函数
  • 函数原型
    • typedef void(*sighandler t)(int);
    • sighandler_t signal(int signum,sighandler_t handler);
  • 函数参数
    • signum:信号编号
    • handler:信号处理函数
  • 信号四要素:(man)
    • 编号
    • 名字
    • 默认处理动作
    • 信号是如何产生的

给一个没有读端的管道写数据,会产生SIGPIPE信号。

 1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<sys/types.h>
  5 #include<unistd.h>
  6 #include<sys/wait.h>
  7 
  8 //信号处理函数
  9 void sighandler(int signo){
 10     printf("signo==[%d]\n",signo);
 11 }
 12 
 13 
 14 int main()
 15 {   
 16     //创建管道
 17     //int pipe(int pipefd[2])
 18     int fd[2];
 19     int ret = pipe(fd);
 20     if(ret<0)
 21     {   
 22         perror("pipe error");
 23         return -1;
 24     }
 25     
 26     //注册SIGPIPE信号处理函数
 27     signal(SIGPIPE,sighandler);
 28     
 29     //关闭读端
 30     closed(fd[0]);
 31     
 32     write(fd[1],"hello world",strlen("hello world"));
 33     
 34     return 0;
 35 }

kill函数/命令

  • 描述:给指定进程发送指定信号
  • kill命令:kill -SIGKILL 进程PID
  • kill函数原型:int kill(pid_t pid,int sig);
  • 返回值: 成功:0,失败 -1
  • 函数参数
    • sig信号参数:不推荐直接使用数字,应使用宏名,因为不同操作系统信号编号可能不同,但名称一致。
    • pid参数:
      • pid>0:发送信号给指定的进程(基本只用这一个)
      • pid=0:发送信号给与调用kill函数进程属于同一进程组的所有进程
      • pid<-1:取|pid|发给对应进程组
      • pid=-1:发送给进程有权限发送的系统中所有进程。

abort函数raise函数:

  • raise函数
    • 函数描述:当前进程给自己发送信号
    • 函数原型:int raise(int sig);
    • 返回值:0成功。失败非0
    • 函数拓展:raise(signo) == kill(getpid(),signo);
  • abort函数
    • 函数描述:给自己发送终止信号,6)SIGABRT 并产生core文件
    • 函数原型:void abort(void);
    • 函数拓展:abort() = kill(getpid(),SIGABRT);

alam函数

  • 函数原型:unsigned int alarm(unsigned int seconds);
  • 函数描述:设置定时器。在指定seconds后,内核会给当前进程发送(14)SIGALRM信号。进程收到该信号,默认动作为终止。每个进程有且都有唯一的一个定时器
  • 函数返回值:返回0或剩余的秒数,无失败。

  •  常用操作:取消定时器alarm(0),返回旧闹钟余下秒数。

alarm使用的是自然定时法,与进程状态无关,就绪、运行、挂起(阻塞、暂停)、终止、僵尸...无论进程处于何种状态,alarm都计时。

 //测试alarm函数。
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<sys/types.h>
  5 #include<unistd.h>
  6 #include<signal.h>
  7 
  8 
  9 void sighandler(int signo){
 10     printf("signo==[%d]\n",signo);
 11 }
 12 
 13 int main()
 14 {   
 15     
 16     signal(SIGALRM,sighandler); 
 17     
 18     int n =alarm(5);
 19     printf("n==[%d]\n",n);
 20     
 21     sleep(2);
 22     n = alarm(1);
 23     printf("n==[%d]\n",n);
 24     sleep(10);
 25     
 26     return 0;
 27 
 28 }

测试电脑1秒钟能写多少个数

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<sys/types.h>
  5 #include<unistd.h>
  6 #include<signal.h>
  7 
  8 int main()
  9 {
 10     alarm(1);
 11     int i =0;
 12     while(1)
 13     {
 14         printf("[%d]  ",i++);
 15     }
 16     return 0;
 17 }
~       

 setitimer函数

  • 函数原型      
    • int setitimer(int which, const struct itimerval *new_value,  struct itimerval *old_value);

  • 函数描述
    • 设置定时器(闹钟),可代替alarm函数,精度微秒us,可以实现周期定时。

  • 函数返回值
    • 成功:0;
    • 失败:-1,设置errno值
  • 函数参数:
    • which:指定定时方式
      • 自然定时:ITIMER_REAL → 14SIGALRM计算自然时间
      • 虚拟空间计时(用户空间):ITIMER_VIRTUAL → 26SIGVTALRM  只计算进程占用cpu的时间
      • 运行时计时(用户+内核):ITIMER_PROF → 27SIGPROF计算占用cpu及执行系统调用的时间
    • new_value:struct itimerval, 负责设定timeout时间。
      • itimerval.it_value: 设定第一次执行function所延迟的秒数
      • itimerval.it_interval: 设定以后每几秒执行function
  • old_value: 存放旧的timeout值,一般指定为NULL
  • struct itimerval {

        struct timerval it_interval; // 闹钟触发周期

        struct timerval it_value; // 闹钟触发时间

      };

      struct timeval {

        long tv_sec;                         //

        long tv_usec;                       // 微秒

     }             

setitimer练习

  //setitimer练习
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<sys/types.h>
  5 #include<unistd.h>
  6 #include<signal.h>
  7 #include<sys/time.h>
  8 
  9 void sighandler(int signo)
 10 {
 11     printf("signo==[%d]\n",signo);
 12 }
 13 
 14 int main()
 15 {
 16 
 17     //注册SIGALRM信号处理函数
 18     signal(SIGALRM,sighandler);
 19 
 20     struct itimerval tm;
 21     //周期性时间赋值
 22     tm.it_interval.tv_sec = 1;
 23     tm.it_interval.tv_usec = 0;
 24     //第一次触发的时间
 25     tm.it_value.tv_sec =3;
 26     tm.it_value.tv_usec = 0;
 27 
 28     setitimer(ITIMER_REAL,&tm,NULL);
 29 
 30 
 31     while(1)
 32     {
 33         sleep(1);
 34     }
 35     return 0;
 36 }
~                                                                                                                       
~                     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值