10.19 sleep,nanosleep以及clock_nanosleep函数

我们已经在本书中多次使用了函数sleep,我们也在图10.7以及图10.8中展示了两个有缺陷的sleep函数的实现。

  1. #include <unistd.h>
  2. unisgned int sleep(unsigned int seconds);
  3. Returns:0 or number of unslept seconds.

该函数会造成进程挂起直到如下两个条件中至少一个为止:

  1. seconds指定的系统时间到;
  2. 一个信号被进程捕获并且该信号处理函数返回;

与函数alarm一样,该函数的实际返回时间可能会比请求的时间稍微晚一些,因为其他系统活动的影响。

在上述第一种情况下,返回值是0,当因为一些信号的出现导致sleep函数提前返回(第二种情况),返回值是还没有sleep完成的秒数。

虽然sleep函数可以使用函数alarm实现(10.10节),但是对此并不做要求.如果同时使用函数alarm与sleep,二者可能会相互影响,而POSIX.1标准对于这些影响并没有相关要求。举例来说,如果我们执行函数sleep(10),等待3秒钟以后,在执行sleep(5),那么会发生什么呢?sleep函数将在5秒钟后返回(假设其他信号并没有在这段时间内被捕获到),但是在2秒钟以后是否会产生信号SIGALRM呢?这一细节与实现有关。

FreeBSD 8.0, Linux 3.2.0, Mac OS X 10.6.8以及Solaris 10使用函数nanosleep函数来实现sleep函数,nanosleep函数可以实现与alarm定时器的独立,为了保证可移植,你不能对sleep函数的实现做任何假设,但是如果你想要混合使用函数sleep与其他任何的时间函数的话,你需要意识到可能的影响。

Example

图10.29显示了POSIX.1中sleep函数的实现,该函数是图10.7中函数实现的一个修改,在图10.7中的可靠地处理了信号,避免了之前实现中可能出现的竞态条件,但是我们仍然没有处理与早先设置的定时器的冲突(虽然这些影响在POSIX.1中并没有定义)

  1. #include "apue.h"
  2. static void sig_alrm(int signo)
  3. {
  4. /*nothing to do,just returning wakes up sigsuspend() */
  5. }
  6. unsigned int sleep(unsigned int seconds)
  7. {
  8. struct sigaction newact, oldact;
  9. sigset_t newmask, oldmask, suspmask;
  10. unsigned int unslept;
  11. /*set our handler, save previous information */
  12. newact.sa_handler = sig_alrm;
  13. sigemptyset(&newact.sa_mask);
  14. newact.sa_flags = 0;
  15. sigaction(SIGALRM, &newact, &oldact);
  16. /*block SIGALRM and save current signal mask */
  17. sigempty(&newmask);
  18. sigaddset(&newmask, SIGALRM);
  19. sigprocmask(SIG_BLOCK, &newmask, &oldmask);
  20. alarm(seconds);
  21. suspmask = oldmask;
  22. /*make sure SIGALRM isn‘t blockedd */
  23. sigdelset(&suspmask, SIGALRM);
  24. /*wait for any signal to be canught */
  25. sigsuspend(&suspmask);
  26. /*some signal has been caught, SIGALRM is now blocked */
  27. unslept = alarm(0);
  28. /*reset previous action */
  29. sigaction(SIGALRM, &oldact, NULL);
  30. /*reset signal mask, which unblocks SIGALRM */
  31. sigprocmask(SIG_SETMASK, &oldmask, NULL);
  32. return (unslept);
  33. }

Figure 10.29 Reliable implementation of sleep

上述实现使用了比图10.7中更多的代码来实现,我们并没有使用分支跳转语句,因此这对于其他的被SIGALRM中断的信号处理函数没有任何影响。

函数nanosleep与sleep函数类似,但是提供了纳秒级的时间精度;

  1. #include <time.h>
  2. int nanosleep(const struct timespec *reqtp, struct timespec *remtp);
  3. Return: 0 if slept for requested time or -1 on error.

该函数将会使得调用进程处于挂起状态,直到请求的时间到达或者是被信号中断。参数reqtp指定了需要睡眠的秒数与纳秒数,如果在睡眠中途被信号中断,且进程没有终止的话,timespec结构指针remtp指向的结构将保存剩余的睡眠时间,如果我们对于未睡眠时间不感兴趣的话,我们可以把这一时间设置为NULL.

如果系统不支持纳秒时间精度的话,请求时间将被向上取整,因为函数nanosleep并不涉及任何信号的产生,我们可以放心大胆地使用它而不用担心与其他函数相互影响。

nanosleep函数曾经属于the Single Unix Specification中的Timers选项,但是在SUSv4版本中被加入到了基本要求。

随着多系统时钟的引入,我们需要一种方法来挂起调用线程,使用一个特殊时钟来实现一段延时。函数clock_nanosleep实现了这一功能。

  1. #include <time.h>
  2. int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *reqtp, struct timespec *remtp);
  3. Returns: 0 if slept for requested time or error number on failure.

参数clock_id用于指定延时是相对于哪一种时钟时间进行的评估。其可选数值如图6.8所示。参数flags用于控制延时是绝对的还是相对的,当flags被设置为0的时候,睡眠时间是相对的(想要睡眠多久),当其数值被设置为TIMER_ABSTIME的时候,睡眠时间是绝对的,比如说,我们需要一直睡眠直到时钟到达指定的时间,这个时候参数remtp是没有被使用的。其他参数reqtp以及remtp,与函数nanosleep相同。

除了返回错误的情况,调用

clock_nanosleep(CLOCK_REALTIME, 0, reqtp, remtp);

与如下调用有着完全相同的作用

nanosleep(reqtp, remtp);

使用相对睡眠的问题是一些应用对于睡眠的时间要求比较精确,但是相对睡眠时间可能会导致实际睡眠时间比期望的时间更长。举例来说,如果一个应用程序想要周期性执行一个任务,那么它可能需要获取当前时间,然后计算到达下一次执行任务的时间间隔,然后调用函数nanosleep,因为获取到当前时间的时刻与nanosleep函数被调用的时刻可能因为系统调度或者是抢占的原因,导致这两个时间点间隔较长,从而导致实际设置的时间长度比期望的更长,这种情况下,使用一个绝对时间就可以很好地改善定时精度,即是时间共享的调度其可能在睡眠时间已经结束的时候无法保证立即执行我们的任务。

在早期版本的the Single UNIX Specification中,函数clock_nanosleep属于Clock Selection选项,但是在SUSv4中,被移到了基本要求中了。

来自为知笔记(Wiz)

时间: 2024-10-14 04:54:12

10.19 sleep,nanosleep以及clock_nanosleep函数的相关文章

Scrum会议10.19

Scrum会议 组名称:好好学习 项目名称:记账本 参会成员:林莉(Master)胡丽娜 宫丽君 汪东涵 时间:2016.10.19 已完成内容: 1.完成新项目的查找,查找学姐的代码和项目. 2.理解学习代码和项目. 计划完成: 1.胡丽娜:记录会议内容,写随笔更新博客. 2.林莉:新项目的查找. 3.汪东涵:项目代码和功能的理解. 4.张金生:学习功能. 燃尽图:

jQuery中10个非常有用的遍历函数

使用jQuery,可以 很容易的选择HTML元素.但有些时候,在HTML结构较为复杂时,提炼我们选择的元素就是一件麻烦的事情.在这篇教程中,我们将探讨十种方 法去精炼和扩展我们将要操作的集合. HTML 首先,让我们看看下图所示的简单的页面,通过这个教程我们将选择这些元素. div.container是包裹元素: div.photo.div.title.div.rating是div.container的直接子级: 每个div.star是div.rating的子级: 当div.satr的class

魏韦新:原油跌宕起伏,EIA登陆,10.19原油沥青操作建议

魏韦新:原油跌宕起伏,EIA登陆,10.19原油沥青操作建议 很多朋友是套完空单又套多单,为什么别人做原油,你也做,但别人赚钱了,而你还在为解套还烦着.每天看新闻说谁谁炒银原油赚钱买房买车了,你羡慕吗?不要跟我说不,你有!但你在羡慕别人的同时你有想过这是为什么吗?难道是你技术比别人差?还是说你比别人笨?不是!都不是!别人赚到钱而你亏钱的原因只有一个,那就是人家有一个好的指导老师,一个好的理财团队为他服务而你没有,仅此而已! 魏韦新--昨日做单回顾 昨天魏韦新一直在等待做空的机会,亚欧两盘行情清淡

一周随笔--15.10.19

一周新知识点记录(15.10.19) 一.ipad——UIPopoverController UIPopoverController继承自NSObject,因此不具备显示能力,它是通过其中的内容控制器显示的内容的.  UIPopoverController使用四部曲: 一.创建UIPopoverController的内容控制器 二.根据内容控制器初始化UIPopoverController对象 三.设置UIPopoverController对象的尺寸 四.显示UIPopoverControlle

10.19 iptables规则备份和恢复 10.20 firewalld的9个zone 10.21

七周五次课 10.19 iptables规则备份和恢复 10.20 firewalld的9个zone 10.21 firewalld关于zone的操作 10.22 firewalld关于service的操作 10.19 iptables规则备份和恢复 10.20 firewalld的9个zone 启动firewalld防火墙,关闭iptables 查看所有的zone和默认的zone 10.21 firewalld关于zone的操作 设置默认zone 设置网卡的zone 10.22 firewal

10.19 iptables规则备份和恢复 10.20 firewalld

10.19 iptables规则备份和恢复 Linux防火墙-netfilter 1. iptables规则保存: 默认规则保存到:/etc/sysconfig/iptables文件中. [[email protected] ~]# service iptables save 2. iptables规则备份(保存)到指定路径: [[email protected] ~]# iptables-save > /tmp/ipt.txt 3. iptables规则清空 : [[email protect

10.19 iptables规则备份和恢复 firewalld的9个zone firewalld关

10.19 iptables规则备份和恢复10.20 firewalld的9个zone 10.21 firewalld关于zone的操作10.22 firewalld关于service的操作 原文地址:http://blog.51cto.com/13107353/2144951

2019.10.19初赛滚粗后的日子

写在故事的前面的话 人生中第一次考CSP-S,然后考得有点自闭,我想我写这篇blog并不是想要说AFO之类的话,相反,我觉得自己应该继续坚持下去的丫子.自己以前欠了很多知识,以前是自己初中时期的不认真,现在我就把自己当成是高一才学OI的萌新,忘记过去对自己的一些期望,重新开始自己的OI生涯. 2019.10.19 今天在自闭完了之后还是逐渐接受了初赛没有多大几率过的事实,开始复习起之前学的东西.首先,今天开始复习树形DP(入门).list如下: Park visit (已过) 没有上司的舞会 (

10个Python set 常用操作函数!

今天为大家带来的内容是10个Python set 常用操作函数!(附带详细解答)文章内容具有不错的参考意义,希望在此能够对各位有所帮助. 集合对象是一组无序排列的可哈希的值,集合成员可以做字典中的键.集合支持用in和not in操作符检查成员,由len()内建函数得到集合的基数(大小), 用 for 循环迭代集合的成员.但是因为集合本身是无序的,不可以为集合创建索引或执行切片(slice)操作,也没有键(keys)可用来获取集合中元素的值. set和dict一样,只是没有value,相当于dic