signal和alarm实现不精确的定时功能

1、alarm()函数

  引用头文件:#include <unistd.h>;

  函数标准式:unsigned int alarm(unsigned int seconds);

  功能与作用:alarm()函数的主要功能是设置信号传送闹钟,即用来设置信号SIGALRM在经过参数seconds秒数后发送给目前的进程。

        如果未设置信号SIGALARM的处理函数,那么alarm()默认处理终止进程。

  函数返回值:如果在seconds秒内再次调用了alarm函数设置了新的闹钟,则后面定时器的设置将覆盖前面的设置,即之前设置的秒数被新的闹钟时间取代;

        当参数seconds为0时,之前设置的定时器闹钟将被取消,并将剩下的时间返回。

2、Signal ()函数

  设置某一信号的对应动作。

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

第一个参数signum:指明了所要处理的信号类型,它可以取除了SIGKILL和SIGSTOP外的任何一种信号。   
第二个参数handler:描述了与信号关联的动作。

此函数必须在signal()被调用前申明,handler中为这个函数的名字。当接收到一个类型为sig的信号时,就执行handler 所指定的函数。

(int)signum是传递给它的唯一参数。执行了signal()调用后,进程只要接收到类型为sig的信号,不管其正在执行程序的哪一部分,就立即执行func()函数。

当func()函数执行结束后,控制权返回进程被中断的那一点继续执行。

3、定时器举例

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sigalrm_fn(int sig)
{
    printf("alarm!\n");
    alarm(2);
    return;
}
int main(void)
{
    signal(SIGALRM,signalrm_fn);
    alarm(2);
    while(1)
    pause();
}
运行结果:每隔2秒钟就会输出一次。

alarm!
alarm!
alarm!

4、信号

 信号的处理:信号的处理有三种方法,分别是:忽略(SIG_IGN)、捕捉和默认动作(SIG_DFL)

1)忽略信号,大多数信号可以使用这个方式来处理,但是有两种信号不能被忽略(分别是 SIGKILLSIGSTOP)。

因为他们向内核和超级用户提供了进程终止和停止的可靠方法,如果忽略了,那么这个进程就变成了没人能管理的的进程,显然是内核设计者不希望看到的场景

2)捕捉信号,需要告诉内核,用户希望如何处理某一种信号,说白了就是写一个信号处理函数,然后将这个函数告诉内核。当该信号产生时,由内核来调用用户自定义的函数,以此来实现某种信号的处理。

3)系统默认动作,对于每个信号来说,系统都对应由默认的处理动作,当发生了该信号,系统会自动执行。不过,对系统来说,大部分的处理方式都比较粗暴,就是直接杀死该进程。
具体的信号默认动作可以使用man 7 signal来查看系统的具体定义。

signal(SIGPIPE,SIG_IGN);#忽略管道信号

 

 参考:

https://www.cnblogs.com/wuyepeng/p/9788889.html

https://blog.csdn.net/yyyljw/article/details/80741264

 https://www.jianshu.com/p/f445bfeea40a

posted on 2021-07-27 10:43  裸睡的猪  阅读(552)  评论(0编辑  收藏  举报