zoukankan      html  css  js  c++  java
  • 20191324读书笔记8

    第五章 定时器及时钟服务

    硬件定时器

    • 定时器是由时钟源和可编程计数器组成的硬件设备。时钟源通常是一个晶体振荡器,会产生周期性电信号,以精确的频率驱动计数器。使用一个倒计时值对计数器进行编程,每个时钟信号减1。当计数减为0时,计数器向CPU生成一个定时器中断,将计数值重新加载到计数器中,并重复倒计时。计数器周期称为定时器刻度,是系统的基本计时单元。

    个人计算机定时器

    • 实时时钟(RTC) : RTC由一个小型备用电池供电。即使在个人计算机关机时,它 也能连续运行。它用于实时提供时间和日期信息。当Linux启动时,它使用RTC更新系统 时间变量.以与当前时间保持一致。在所有类Unix系统中,时间变量是一个长整数,包含 从1970年1月1日起经过的秒数。
    • 可编程间隔定时器(PIT): PIT是与CPU分离的一个硬件定时器。可 对它进行编程,以提供以毫秒为单位的定时器刻度。在所有I/O设备中,PIT可以最高优先 级IRQ0中断。PIT定时器中断由Linux内核的定时器中断处理程序来处理,为系统操作提 供基本的定时单元,例如进程调度、进程间隔定时器和其他许多定时事件。
    • 多核CPU中的本地定时器:在多核CPU中,每个核都 是一个独立的处理器,它有自己的本地定时器,由CPU时钟驱动。
    • 高分辨率定时器:大多数电脑都有一个时间戳定时器(TSC),由系统时钟驱动。它 的内容可通过64位TSC寄存器读取。由于不同系统主板的时钟频率可能不同,TSC不适合 作为实时设备,但它"提供纳秒级的定时器分辨率。一些高端个人计算机可能还配备有专用 高速定时器,以提供纳秒级定时器分辨率.

    CPU操作

    • 每个CPU都有一个程序计数器(PC),也称为指令指针(IP),以及一个标志或状态寄 存器(SR)、一个堆栈指针(SP)和几个通用寄存器,当PC指向内存中要执行的下一条指 令时,SR包含CPU的当前状态,如操作模式、中断掩码和条件码,SP指向当前堆栈栈顶。
    • CPU操作可通过无限循环进行建模。

    中断处理

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

    时钟服务函数

    • clock_t times(struct tms *buf);可用于获取某进程的具体执行时间。它将进程时间存储在struct tms buf中:
    clock_t		// user mode time
    clock_t	tms_stime;	// system mode time
    clock_t	tms_cutime;	// user time of children
    clock_t	tms_cstime;	// system time of children
    
    • date:打印或设置系统日期和时间。
    • time:报告进程在用户模式和系统模式下的执行时间和总时间。
    • hwclock:查询并设置硬件时钟(RTC),也可以通过BIOS来完成。
    • 间隔定时器的值用以下结构体(在<sys/time.h>中)定义:

    struct itimerval {
    struct timeval it_inteirval; /* interval for periodic timer / struct timeval it_value; / time until next expiration /
    };
    struct timeval (
    time_t tv_sec; /
    seconds /
    suseconds_t tv_usec; /
    microseconds */
    );

    临界区

    在基本代码系统中,只有一种执行实体,即任务,一次只执行一个任务。某任务在收到切换命令、进入休眠或退出之前,会一直执行下去。此外,任务
    换只会发生在操作结束时,而不会发生在任何操作过程中。因此,任务之间没有竞争,因此在基本代码系统中没有临界区。但是,一旦我们将中断引人
    系统,情况就会改变。有两种类型的实体来执行中断,分别是任务和中断处理程序,它们可能会争夺系统中的同一(共享)数据对象。例如,当某任务请
    求间隔定时器时,必须将请求作为定时器队列元素输入timerQueue中。当某任务修改timerQueue 时,如果出现定时器中断,它将转移任务以执行中
    断处理程序,可能会改动同一 timerQueue,造成竞态条件。因此,timerQueue是临界区,必须对它进行保护,以确保它一次只能由一个执行实体访
    问。同样,当某进程在sleep()函数过程中执行时,可能被转移到执行中断处理程序,即可执行wakeup(),以试图在进程完成休眠操作之前唤醒它,
    从而导致另一个竟态条件。所以,问题是如何防止任务和中断处理程序相互干扰。

    实践

    示例5.3:time.c

    #include <stdio.h>
    #include <time.h>
    time_t start,end;
    int main()
    {
    int i;
    start = time(NULL);
    printf ("start=%ld
    ", start);
    for (i=0; i<123456789; i++); // delay to simulate computation
    end = time (NULL);
    printf ("end =%ld time=%ld
    " , end, end-start);
    }
    

    运行截图

    示例5.1 gettimeofday.c

    #include <stdio.h>
    #include <string.h>
    #include <sys/time.h>
    
    int main()
    {
        struct timeval tv;
    
        gettimeofday(&tv, NULL);
    
        printf("tv_sec: %d
    ", tv.tv_sec);
        printf("tv_usec: %d
    ", tv.tv_usec);
    
        return 0;
    }
    

    运行截图

  • 相关阅读:
    通用权限管理设计 之 数据库结构设计
    jQuery LigerUI 插件介绍及使用之ligerDateEditor
    jQuery LigerUI 插件介绍及使用之ligerTree
    jQuery LigerUI V1.01(包括API和全部源码) 发布
    jQuery liger ui ligerGrid 打造通用的分页排序查询表格(提供下载)
    jQuery LigerUI V1.1.5 (包括API和全部源码) 发布
    jQuery LigerUI 使用教程表格篇(1)
    jQuery LigerUI V1.0(包括API和全部源码) 发布
    jQuery LigerUI V1.1.0 (包括API和全部源码) 发布
    nginx keepalived
  • 原文地址:https://www.cnblogs.com/pxmxxr/p/15499300.html
Copyright © 2011-2022 走看看