博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POSIX定时器Timer
阅读量:2029 次
发布时间:2019-04-28

本文共 3043 字,大约阅读时间需要 10 分钟。

 

POSIX Timer

间隔定时器 setitimer 有一些重要的缺点,POSIX Timer 对 setitimer 进行了增强,克服了 setitimer 的诸多问题:

  • 首先,一个进程同一时刻只能有一个 timer。假如应用需要同时维护多个 Interval 不同的计时器,必须自己写代码来维护。这非常不方便。使用 POSIX Timer,一个进程可以创建任意多个 Timer。
  • setitmer 计时器时间到达时,只能使用信号方式通知使用 timer 的进程,而 POSIX timer 可以有多种通知方式,比如信号,或者启动线程。
  • 使用 setitimer 时,通知信号的类别不能改变:SIGALARM,SIGPROF 等,而这些都是传统信号,而不是实时信号,因此有 timer overrun 的问题;而 POSIX Timer 则可以使用实时信号。

备注:通过kill –l可以查看系统支持的所有信号列表。编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。

  • setimer 的精度是 ms,POSIX Timer 是针对有实时要求的应用所设计的,接口支持 ns 级别的时钟精度。
函数名 功能描述
timer_create  创建一个新的 Timer;并且指定定时器到时通知机制
timer_delete 删除一个 Timer
timer_gettime Get the time remaining on a POSIX.1b interval timer
timer_settime 开始或者停止某个定时器。
timer_getoverrun 获取丢失的定时通知个数。

使用 Posix Timer 的基本流程很简单,首先创建一个 Timer。创建的时候可以指定该 Timer 的一些特性,比如 clock ID。clock ID 即 Timer 的种类,可以为下表中的任意一种:

POSIX Timer clock ID

Clock ID 描述
CLOCK_REALTIME Settable system-wide real-time clock;
CLOCK_MONOTONIC Nonsettable monotonic clock
CLOCK_PROCESS_CPUTIME_ID Per-process CPU-time clock
CLOCK_THREAD_CPUTIME_ID Per-thread CPU-time clock
  • CLOCK_REALTIME 时间是系统保存的时间,即可以由 date 命令显示的时间,该时间可以重新设置。比如当前时间为上午 10 点 10 分,Timer 打算在 10 分钟后到时。假如 5 分钟后,我用 date 命令修改当前时间为 10 点 10 分,那么 Timer 还会再等十分钟到期,因此实际上 Timer 等待了 15 分钟。假如您希望无论任何人如何修改系统时间,Timer 都严格按照 10 分钟的周期进行触发,那么就可以使用CLOCK_MONOTONIC。
  • CLOCK_PROCESS_CPUTIME_ID 的含义与 setitimer 的 ITIMER_VIRTUAL 类似。计时器只记录当前进程所实际花费的时间;比如还是上面的例子,假设系统非常繁忙,当前进程只能获得 50%的 CPU 时间,为了让进程真正地运行 10 分钟,应该到 10 点 30 分才允许 Timer 到期。
  • CLOCK_THREAD_CPUTIME_ID 以线程为计时实体,当前进程中的某个线程真正地运行了一定时间才触发 Timer。

设置到期通知方式

timer_create 的第二个参数 struct sigevent 用来设置定时器到时时的通知方式。该数据结构如下:

结构sigevent

 struct sigevent {     int sigev_notify; /* Notification method */     int sigev_signo; /* Notification signal */     union sigval sigev_value; /* Data passed with notification */     void (*sigev_notify_function) (union sigval);     /* Function used for thread notification (SIGEV_THREAD) */     void *sigev_notify_attributes;     /* Attributes for notification thread (SIGEV_THREAD) */     pid_t sigev_notify_thread_id;     /* ID of thread to signal (SIGEV_THREAD_ID) */ };

其中sigev_notify 表示通知方式,有如下几种:

POSIX Timer 到期通知方式

通知方式 描述
SIGEV_NONE 定时器到期时不产生通知。。。
SIGEV_SIGNAL 定时器到期时将给进程投递一个信号,sigev_signo 可以用来指定使用什么信号。
SIGEV_THREAD 定时器到期时将启动新的线程进行需要的处理
SIGEV_THREAD_ID(仅针对 Linux) 定时器到期时将向指定线程发送信号。
  • 如果采用 SIGEV_NONE 方式,使用者必须调用timer_gettime 函数主动读取定时器已经走过的时间。类似轮询。
  • 如果采用 SIGEV_SIGNAL 方式,使用者可以选择使用什么信号,用 sigev_signo 表示信号值,比如 SIG_ALARM。
  • 如果使用 SIGEV_THREAD 方式,则需要设置 sigev_notify_function,当 Timer 到期时,将使用该函数作为入口启动一个线程来处理信号;sigev_value 保存了传入 sigev_notify_function 的参数。sigev_notify_attributes 如果非空,则应该是一个指向 pthread_attr_t 的指针,用来设置线程的属性(比如 stack 大小,detach 状态等)。
  • SIGEV_THREAD_ID 通常和 SIGEV_SIGNAL 联合使用,这样当 Timer 到期时,系统会向由 sigev_notify_thread_id 指定的线程发送信号,否则可能进程中的任意线程都可能收到该信号。这个选项是 Linux 对 POSIX 标准的扩展,目前主要是 GLibc 在实现 SIGEV_THREAD 的时候使用到,应用程序很少会需要用到这种模式。

————————————————

版权声明:本文为CSDN博主「许振坪」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/benkaoya/java/article/details/17342711

 

你可能感兴趣的文章
springmvc事务回滚失效
查看>>
Java 8的五大开发技巧
查看>>
多线程中的注意点
查看>>
netty4 Handler的执行顺序
查看>>
ZooKeeper原理及使用
查看>>
guava学习--事件驱动模型
查看>>
guava学习--hashing
查看>>
guava学习--AsyncFunction
查看>>
guava学习--monitor
查看>>
guava学习--FutureCallback
查看>>
golang的数据类型之布尔类型
查看>>
golang的数据类型之字符类型
查看>>
安装MySQL
查看>>
golang简介
查看>>
golang的数据类型之整型类型
查看>>
安装go版本
查看>>
golang的数据类型之基本数据类型的默认值和转换
查看>>
golang的数据类型之浮点类型
查看>>
golang的数据类型之字符串类型
查看>>
标识符
查看>>