• 《Unix/Linux系统编程》第五章学习笔记


    定时器及时钟服务

    • 硬件定时器
    • CPU操作
    • 中断处理
    • 定时器相关的系统调用、库函数
    • 进程间隔定时器
    • 项目实践
    • 临界区

    定时器

    定时器由时钟源和可编程计数器组成。时钟源会产生周期性电信号。计数器减为0时,计数器向CPU生成一个定时器中断,计数器周期称为定时器刻度,是系统的基本计时单元。

    • 实时时钟(RTC)
      即使在个人计算机关机时,它也能连续运行。它用于实时提供时间和日期信息。
    • 可编程间隔定时器(PIT)
      PIT与CPU分离,提供以毫秒为单位的定时器刻度,在所有I/O设备中,PIT可以最高优先级IRO0中断,PIT定时器中断由Linux内核的定时器中断处理程序来处理。
    • 多核CPU中的本地计时器
      每个核都是一个独立的处理器,有自己的本地计时器。
    • 高分辨率计时器
      时间戳定时器(TSC)不适合作为实时设备,可提供纳秒级的定时器分辨率。

    CPU操作和中断处理

    由于无效地址、非法指令、越权等问题,可能会出现异常或陷阱。CPU会异常处理程序,当指令执行结束时,CPU会检查挂起的中断。如果有中断请求,但CPU未处于接受中断的状态,CPU会忽略中断,继续执行指令。中断处理和异常处理在操作系统内核中进行。对于每个中断,可以编程中断控制器来生成唯一的中断向量,标识中断源。CPU会用它作为中断向量表,其中包含指向中断处理程序入口地址的指针,终端结束后,CPU恢复指令正常执行。

    相关系统调用

    #include <sys/time.h>
    int gettimeofday(struct timeval *tv, struct timezone *tz);
    int settimeofday(const struct timeval *tv, const struct timezone *tz);
    

    因为timezone已过期,所以设置为NULL

    • gettimeofday.c:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/time.h>
    
    struct timeval t;
    
    int main ()
    {
      gettimeofday(&t, NULL);
      printf("sec=%ld usec=%d
    ", t.tv_sec, t.tv_usec);
      printf((char *)ctime(&t.tv_sec));
    }
    

    运行结果如下:

    遇到问题,第二个printf运行结果出错Segmentation fault (core dumped),查阅得知这多为内存不当操作造成。空指针、野指针的读写操作,数组越界访问,破坏常量等
    *还未修改成功。

    • settimeofday.c:
    #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 = settimeofday(&t,NULL);
    	if (!r){
    		printf("settimeofday() failed
    ");
    		exit(1);
    	}
    	gettimeofday(&t,NULL);
    	printf("sec=%ld usec=%ld
    ",t.tv_sec,t.tv_usec);
    	printf("%s",ctime(&t.tv_sec));
    }
    

    运行结果:

    产生的结果只是暂时的,Linux内核能够使用实时时钟来纠正系统时间与实时时间之间的任何偏差。

    • time系统调用
    #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++)
    	end = time(NULL);
    	printf("end =%ld time=%ld
    ",end,end-start);
    }
    

    运行结果

    间隔定时器

    • ITIMER_REAL:实时减少
    • ITIMER_VIRTUAL:仅当进程在用户模式下减少。
    • ITIMER_PROF:当进程在用户模式和系统模式下执行时减少。

    项目实践

    • 提供多任务系统的代码
    • 添加定时器和定时器中断
    • 实现任务间隔定时器
    • 通过时间片在系统和任务调度中实现临界区
  • 相关阅读:
    5月13日工作日志(需求规格说明书4.0)
    第十次会议
    5月21日日志
    5月12日工作日志
    关于游戏平衡性——王者荣耀英雄伤害数值参考
    每天一点新东西(1)
    我在都匀做网优(补)
    我在都匀做网优
    不算新的开始
    input的focus事件时,鼠标光标在最后
  • 原文地址:https://www.cnblogs.com/shoudeyunkaijianyueming/p/15510619.html
Copyright © 2020-2023  润新知