• ch5(定时器和时钟)学习笔记


    知识点归纳

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

    时钟源通常是一个晶体震荡器,产生周期性电信号

    当计数器减为0时,向CPU生成定时器中断

    当CPU遇到异常时,会进行预设的异常处理

    中断是外部设备请求CPU服务

    CPU是否处理中断取决于它的状态寄存器是否屏蔽了中断

    问题与解决思路

    中断是如何实现的?

    中断的本质是处理器对外开放的实时受控接口。
    一个没有中断的计算机体系是决定论的:得知某个时刻CPU和内存的全部数据状态,就可以推衍出未来的全部过程。这样的计算机无法交互,只是个加速器。
    添加中断后,计算机指定了会兼容哪些外部命令,并设定服务程序,这种服务可能打断当前任务。这使得CPU“正在执行的程序”与“随时可能发生的服务”,二者形成了异步关系,外界输入的引入使得计算机程序不再是决定论。由人实时控制的中断输入,是无法预测的。再将中断响应规则化,推广开,非计算机科学人群就能控制计算机,发挥创造力。

    既然硬件能干扰到CPU的正常的指令执行,那么CPU就必须能感知到干扰信号,所谓的干扰信号就是这里所说的中断信号。

    CPU的工作粒度是机器指令级别,那么在每条机器指令执行结束后都会检查一下是否中断信号产生。

    这里的实现可能是轮询。这就好比你在玩游戏,此时如果有人喊你的名字(中断信号)干扰你玩游戏那么你立刻就能听到
    但人的大脑里有一直在轮询“有没有人喊我的名字?有没有人喊我的名字?有没有人喊我的名字?”了吗?并没有。人脑的中断检查机制是及其高效的。

    CPU的硬件特性决定中断处理机制也及其高效。

    当那个管脚电平变低(或者变高)的时候,cpu就会被打断,并从特定地址开始执行。
    就像cpu的reset被拉低的时候一定会复位并从0地址开始执行一样,都是硬件的结构决定的。

    实践内容

    gettimeofday()

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <sys/time.h>
      4 #include <time.h>
      5 
      6 int main(){
      7     struct timeval t;
      8     gettimeofday(&t,NULL);
      9     printf("sec = %ld , usec = %d
    ",t.tv_sec,t.tv_usec);
     10     printf((char*)ctime(&t.tv_sec));
     11     return 0;
     12 }
    
    

    settimeofday()

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <sys/time.h>
      4 #include <time.h>
      5 
      6 int main(){
      7     struct timeval t;
      8     t.tv_sec = 123456789;
      9     t.tv_usec = 0;
     10     int r = settimeofday(&t,NULL);
     11     if(!r){
     12         printf("settimeofdat() failed
    ");
     13         return -1;
     14     }
     15     gettimeofday(&t,NULL);
     16     printf("sec = %ld , usec = %ld
    ",t.tv_sec,t.tv_usec);
     17     printf("%s",ctime(&t.tv_sec));
     18     return 0;
     19 }
    
    

    Linux内核能够纠正系统时间和实时时间的偏差

    time()

    获取以秒为单位的系统时间

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <time.h>
      4 
      5 int main(){
      6     time_t start , end;
      7     start = time(NULL);
      8     printf("start = %ld
    ",start);
      9     for(int i=0;i<123456789;i++);
     10     end = time(NULL);
     11     printf("end = %ld
    ",end);
     12     printf("time = %ld
    ",end-start);
     13     return 0;
     14 }
    

    setitimer()

      1 #include <signal.h>
      2 #include <stdio.h>
      3 #include <sys/time.h>
      4 int count = 0;
      5 struct itimerval t;
      6 void timer_handler(int sig)
      7 {
      8     printf("timer_handler: signal=%d count=%d
    ", sig, ++count);
      9     if (count>=8){
     10         printf("cancel timer
    ");
     11         t.it_value.tv_sec = 0;
     12         t.it_value.tv_usec = 0;
     13         setitimer(ITIMER_VIRTUAL, &t, NULL);
     14     }
     15 }
     16 int main()
     17 {
     18     struct itimerval timer;
     19     // Install timer_handler as SIGVTALRM signal handler
     20     signal(SIGVTALRM, timer_handler);
     21     // Configure the timer to expire after 100 msec
     22     timer.it_value.tv_sec = 0;
     23     timer.it_value.tv_usec = 100000; // 100000 nsec
     24     // and every 1 sec afterward
     25     timer.it_interval.tv_sec = 1;
     26     timer.it_interval.tv_usec = 0;
     27     // Start a VIRTUAL itimer
     28     setitimer(ITIMER_VIRTUAL, &timer, NULL);
     29     printf("looping: enter Control-C to terminate
    ");
     30     while(1);
     31 }
    
    

  • 相关阅读:
    报错处理——TypeError: Dog() takes no arguments
    python笔记——爬虫练习
    python笔记——爬虫原理
    Numpy入门练习
    python学习资源
    python笔记——函数的参数(位置参数、默认参数、可变参数、关键字参数、命名关键字参数、参数组合)
    Spyder快捷键
    python笔记——常用的内置函数
    python笔记——dict和set
    python笔记——for和while循环、if条件判断、input输入
  • 原文地址:https://www.cnblogs.com/cfqlovem-521/p/15520777.html
Copyright © 2020-2023  润新知