zoukankan      html  css  js  c++  java
  • 定时器及时钟服务

    Ch5 定时器及时钟服务

    代码链接:https://gitee.com/xin_yu_liu/unix-linux-code

    本章概要:

    • 定时器和定时器服务
    • 硬件定时器的原理
    • CPU操作和中断处理
    • Linux中与定时器相关的系统调用、库 函数和定时器服务命令
    • 进程冋隔定时器、定时器生成的信号

    5.1 硬件定时器

    定时器是由时钟源和可编程计数器组成的硬件设备。

    • 时钟源通常是一个晶体振荡 器,会产生周期性电信号,以精确的频率驱动计数器

    5.2 个人计算机定时器

    5.3 CPU操作

    中断处理和异常处理都在操作系统内核中进行。在大多数情况下,用户级程序无法访问它们,但它们是 理解操作系统(如Linux)定时器服务和信号的关键。

    5.4 中断处理

    • 外部设备(如定时器)的中断被馈送到中断控制器的预定义输入行(Intel 1990 ; Wang 2015),按优先级对中断输入排序,并将具有最高优先级的中断作为中断请求(IRQ)路由 到CPU。

    • 在每条指令执行结束时,如果CPU未处于接受中断的状态,即在CPU的状态寄 存器中屏蔽了中断.它将忽略中断请求.使其处于挂起状态,并继续执行下-条指令。

    • 如果 CPU处于接受中断状态,即中断未被屏蔽.那么CPU将会转移它正常的执行顺序来进行中 断处理对于每个中断,可以编程中断控制器以生成一个唯一编号,叫作中断向量,标识中 断源。在获取中断向量号后,CPU用它作为内存中中断向量表(AMD64 2011 )中的条目索 引,条目包含一个指向中断处理程序入口地址的指针来实际处理中断。

    • 当中断处理结束时, CPU恢复指令的正常执行

    5.5 时钟服务函数

    在几乎所有的操作系统(os)中,操作系统内核都会提供与时钟相关的各种服务,时钟 服务可通过系统调用、库函数和用户级命令调用。

    1. 通过gettimeofday()获取系统时间

      /********* gettimeofday.c £ile***/
      #include <stdio.h>
      #include <stdlib.h>
      #include <sys/time.h>
      stiruct timeval t;
      int main()
      {
      gettimeofday(&tff NULL);
      printf("sec=%ld usec=%d\n", t.tv_sec, t.tv_usec);
      printf((char *)ctime(&t.tv_sec));
      )
      
      
    2. 通过settimeofday()设置系统时间。

      /********* settimeofday.c file***/
      #include <stdio.h>
      #include <stdlib.h>
      #include <sys/time.h>
      #include <time.h>
      struct timeval t;
      int main()
      int r;
      t.tv_sec = 123456789;
      t.tv_usec= 0;
      r = set t: imeof day (&t, NULL);
      if (!r){
      printf (''settimeofday () failed\nz,);
      exit(1);
      }
      gettimeofday(&t, NULL);
      printf("sec=%ld usec=%ld\n"z t.tv_sec, t.tv_usec);
      printf	ctime (&t.tv_sec)) ; // show time in calendar form
      }
      
      
    3. time系统调用。

      /************ time.c file ***********/
      #include <stdio.h>
      #include <time.h>
      time_t start, end;
      int main()
      (
      int i;
      start = time(NULL);
      printf (''start=%ld\nw , start);
      for (i=0; i<123456789; i++); // delay to simulate computation
      end = time (NULL);
      printf (''end =%ld time=%ld\nw , end, end-start);
      
      
    4. time 和 date 命令

      • date:打印或设置系统日期和时间。
      • time:报告进程在用户模式和系统模式下的执行时间和总时间。
      • hwclock:查询并设置硬件时钟(RTC),也可以通过BIOS来完成。

    5.6 时间间隔器

    Linux为每个进程提供了三种不同类型的间隔计时器,可用作进程计时的虚拟时钟。

    间隔定时器由setitimer()系统调用创建。

    getitimer()系统调用返回间隔定时器的状态。

    int getitimer(int which, struct itimerval *curr_value);
    int setitimer(int which, const struct itimeirval *new_value,
    struct itimerval *old_value);
    
    /*********** setitimer.c file *********/
    #include <signal.h>
    #include <Btdia.h>
    #include <sys/time.h>
    int count = 0;
    struct it interval t;
    void tizner_handler(int sig) 
    printf("timer_handler: signal=%d count=%d\n", sig, ++count); if (count>=8)(
    printf(■cancel timer\n");
    t.it_value.tv_sec = 0;
    t.it_value.tv_usec = 0;
    setitimer(ITIMER_VIRTUAL, &t, NULL);
    int main()
    (
    struct itimerval timer;
    // Install timer_handler as SIGVTALRM signal handler signal(SIGVTALRM, timer_handler);
    // Configure the timer to expire after 100 msec
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_usec = 100000; // 100000 nsec
    // and every 1 sec afterward
    timer.it_interval.tv_sec = 1;
    timer.it_interval.tv_usec = 0;
    // Start a VIRTUAL itimer
    setitimer(ITIMER_VIRTUALr	NULL);
    printf("looping: enter Control-C to terminate\n"); while(1);
    

    5.7 REAL模式间隔定时器

    VIRTUAL和PROF模式下的间隔计时器仅在执行进程时才有效。

    • REAL模式冋隔定时器各不相同,因为无论进程是否正在执行,它们都必须由定时器中断处理程序来更新一因此,操作系统内核必须使用额外的数 据结构来处理进程的REAL模式定时器,并在定时器到期或被取消时采取措施。

    5.8 编程项目

  • 相关阅读:
    对图像边缘进行随机均匀采样的C#算法实现
    [淡藤]最近几年在Chinapub上买的书
    重新认识C#: 玩转指针
    又是一年春来到
    需求定律在起着作用
    haha, 愚人节听鱼人歌
    名字就叫奥格工作室!
    effective c++ 第六章
    com 名字对象(1)IBindCtx
    com 名字对象(2)创建名字对象(IMoniker)
  • 原文地址:https://www.cnblogs.com/lxy2019/p/15521596.html
Copyright © 2011-2022 走看看