分类: LINUX

    Heartwork前辈在我前一篇博文多线程条件下的计数器(2)中的回复中提到,

 
nanosleep的问题很好解释,看这里……

The nanosleep() function shall cause the current thread to be suspended from execution until either the time interval specified by the rqtp argument has elapsed or a signal is delivered to the calling thread, and its action is to invoke a signal-catching function or to terminate the process. The suspension time may be longer than requested because the argument value is rounded up to an integer multiple of the sleep resolution or because of the scheduling of other activity by the system. But, except for the case of being interrupted by a signal, the suspension time shall not be less than the time specified by rqtp, as measured by the system clock CLOCK_REALTIME.

The use of the nanosleep() function has no effect on the action or blockage of any signal.

简单来说,这个误差是与调度器的时间片和调度策略有关的,也就是可以通过减小时间片大小和使用实时性更好的调度策略(比如SCHED_RR)来获得更小的分辨率。

 
下来我写了段测试代码,对默认情况和设置调度算法后的nanosleep做了测量。
 
  • #include<stdio.h>
  • #include<stdlib.h>
  • #include<unistd.h>
  • #include<sys/time.h>
  • #include<sched.h>
  • #define COUNT 10000
  • #define MILLION 1000000L
  • #define NANOSECOND 1000
  • int main(int argc,char* argv[])
  • {
  • int i;
  • struct timespec sleeptm;
  • long interval;
  • struct timeval tend,tstart;
  • struct sched_param param;
  • if(argc != 2)
  • {
  • fprintf(stderr,"usage:./test sched_method\n");
  • return -1;
  • }
  • int sched = atoi(argv[1]);
  • param.sched_priority = 1;
  • sched_setscheduler(getpid(),sched,&param);
  • int scheduler = sched_getscheduler(getpid());
  • fprintf(stderr,"default scheduler is %d\n",scheduler);
  • sleeptm.tv_sec = 0;
  • sleeptm.tv_nsec = NANOSECOND;
  • if(gettimeofday(&tstart,NULL)!=0)
  • {
  • fprintf(stderr,"get start time failed \n");
  • return -2;
  • }
  • for(i = 0;i<COUNT;i++)
  • {
  • if(nanosleep(&sleeptm,NULL) != 0)
  • {
  • fprintf(stderr,"the %d sleep failed\n",i);
  • return -3;
  • }
  • }
  • if(gettimeofday(&tend,NULL)!=0)
  • {
  • fprintf(stderr,"get end time failed \n");
  • return -4;
  • }
  • interval = MILLION*(tend.tv_sec - tstart.tv_sec)
  • +(tend.tv_usec-tstart.tv_usec);
  • fprintf(stderr,"the expected time is %d us,but real                                   time cost is %lu us\n",COUNT,interval);
  • return 0;
  • }
  • root@libin:~/program/C/timer# ./test 0
  • default scheduler is 0
  • the expected time is 10000 us,but real time cost is 630624 us
  • root@libin:~/program/C/timer# ./test 1
  • default scheduler is 1
  • the expected time is 10000 us,but real time cost is 67252 us
  • root@libin:~/program/C/timer# ./test 2
  • default scheduler is 2
  • the expected time is 10000 us,but real time cost is 82449 us
 
所谓调度算法值 0 1  2 分别是什么呢?bit/sched.h中定义:
 
  • #define SCHED_OTHER 0
  • #define SCHED_FIFO 1
  • #define SCHED_RR 2
  • #ifdef __USE_GNU
  • # define SCHED_BATCH 3
  • #endif
从结果上看,采用默认的算法是SCHED_OTHER nanosleep是最不准确的,理想情况下,每次睡1us,睡10000次,耗时因该是10ms,实际上耗时是630ms。采用时间片轮转的SCHED_RR nanosleep的计时 要准确一些,耗时为82ms.依次类推。
 
 
至于调度算法如何影响nanosleep,我还不是很清楚,里面还有很多东西需要我继续学习。好久没写博客了,先将这篇不成熟的博文拿出,抛砖引玉。
 
参考文献:
1 UNIX 系统编程
2 Heartwork的回复

【转】nanosleep的精度与调度算法的关系 来自:bean.blog.chinaunix.net的更多相关文章

  1. listener.ora--sqlnet.ora--tnsnames.ora的关系以及手工配置举例(转载:http://blog.chinaunix.net/uid-83572-id-5510.ht)

    listener.ora--sqlnet.ora--tnsnames.ora的关系以及手工配置举例 ====================最近看到好多人说到tns或者数据库不能登录等问题,就索性总结 ...

  2. 峰Spring4学习(5)bean之间的关系和bean的作用范围

    一.bean之间的关系: 1)继承: People.java实体类: package com.cy.entity; public class People { private int id; priv ...

  3. Spring初学之bean之间的关系和bean的作用域

    一.bean之间的关系 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="h ...

  4. Spring -- Bean自己主动装配&amp;Bean之间关系&amp;Bean的作用域

    对于学习spring有帮助的站点:http://jinnianshilongnian.iteye.com/blog/1482071 Bean的自己主动装配 Spring IOC 容器能够自己主动装配 ...

  5. Jaxb 解析 带有继承关系的bean与xml

    具体方法: 1. 在jaxb的setClasstobebounds中,只需要子类的class,无需父类. 2. 父类的前面加如下声明: @XmlAccessorType(XmlAccessType.F ...

  6. nobup 与 后台运行命令

    1. Linux进程状态:R (TASK_RUNNING),可执行状态&运行状态(在run_queue队列里的状态) 2. Linux进程状态:S (TASK_INTERRUPTIBLE),可 ...

  7. Linux epoll 笔记(高并发事件处理机制)

    wiki: Epoll优点: Epoll工作流程: Epoll实现机制: epollevent; Epoll源码分析: Epoll接口: epoll_create; epoll_ctl; epoll_ ...

  8. linux包之procps之ps与top

    概述 阅读man ps页,与man top页,最权威与标准,也清楚 有时候系统管理员可能只关心现在系统中运行着哪些程序,而不想知道有哪些进程在运行.由于一个应用程序可能需要启动多个进程.所以在同等情况 ...

  9. [Freescale]Freescale L3.14.52_1.1.0 yocto build

    可参照:http://blog.csdn.net/wince_lover/article/details/51456745 1. Refer to <基于i.mx6处理器的Yocto项目及Lin ...

随机推荐

  1. 【BZOJ-4213】贪吃蛇 有上下界的费用流

    4213: 贪吃蛇 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 58  Solved: 24[Submit][Status][Discuss] Desc ...

  2. 如何利用SmartGit将一个已经写好的项目push到github

    首先在github上创建一个repository, 然后在SmartGit中 点击有上角的repository然后选择Add or Create...然后点击那个文件夹的图标之后选中自己的项目的问题件 ...

  3. 什么是ECMA标准

    是1961年成立的旨在建立统一的电脑操作格式标准,包括程序语言和输入输出的组织. 官方ECMA标准列表: http://www.ecma-international.org/publications/ ...

  4. 洛谷P3398 仓鼠找sugar

    题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c) ...

  5. glibc resolv/res_send.c getaddrinfo() buffer stack smash when dealing malformation big DNS Response Package

    catalogue . 漏洞简述 . 调试环境搭建 . 漏洞利用 . 漏洞分析 . 缓解修复方案 1. 漏洞简述 0x1: 函数调用顺序 getaddrinfo (getaddrinfo.c) -&g ...

  6. Linux 之 编译器 gcc/g++参数详解

    2016年12月9日16:48:53 ----------------------------- 内容目录: [介绍] gcc and g++分别是gnu的c & c++编译器 gcc/g++ ...

  7. 《JavaScript权威指南》学习笔记 第五天 window对象的方法。

    前天和昨天大致浏览了犀牛书的函数.类与模块.正则表达式.JavaScript扩展.以及服务端的js.这些方面对于我目前的水平来说比较难,一些最基本的概念都不能领会.不过最复杂的知识占用平时使用的20% ...

  8. 给linux添加yum源。

    在玩linux的过程中,经常会下载一些源码包.软件大多是国外人写的,由于众所周知的原因,网络下载很慢. 所以想到了更新yum源的方法. 我的linux版本是CentOS6.3的. 以下参考百度. 1, ...

  9. f.lux for Linux安装

    1.安装f.luxsudo add-apt-repository ppa:kilian/f.lux sudo apt-get update sudo apt-get install fluxgui 2 ...

  10. JavaScript Ajax之美~

    JavaScript Ajax之美~ 曾经有一段时期,因为开发人员对JavaScript的滥用导致其遭受了一段时间的冷门时期,不被大家看好,后来,到了2005年,Google公司的很多技术都是用了aj ...