(笔记)Linux内核学习(八)之定时器和时间管理-程序员宅基地

技术标签: 数据结构与算法  

 

一 内核中的时间观念

       内核在硬件的帮助下计算和管理时间。硬件为内核提供一个系统定时器用以计算流逝的时间。系

 统定时器以某种频率自行触发,产生时钟中断,进入内核时钟中断处理程序中进行处理。

       墙上时间和系统运行时间根据时钟间隔来计算。

利用时间中断周期执行的工作:

       更新系统运行时间;

       更新实际时间;

       在smp系统上,均衡调度程序中各处理器上运行队列;

       检查当前进程是否用尽了时间片,重新进行调度;

       运行超时的动态定时器;

       更新资源消耗和处理器时间的统计值;

二 节拍率

       系统定时器的频率;通过静态预处理定义的——HZ;系统启动按照HZ值对硬件进行设置。体系结构不同,HZ值也不同;HZ可变的。

    //内核时间频率

    #define HZ 1000

提高节拍率中断产生更加频繁带来的好处:

       提高时间驱动事件的解析度;

       提高时间驱动事件的准确度;

       内核定时器以更高的频度和准确度;

       依赖顶上执行的系统调用poll()和select()能更高的精度运行;

       系统时间测量更精细;

       提高进程抢占的准确度;

提高节拍率带来的副作用:

       中断频率增高系统负担增加;

       中断处理程序占用处理器时间增多;

       频繁打断处理器高速缓存;

节拍率HZ值需要在其中进行平衡。

 

三 jiffies

  jiffies:全局变量,用来记录自系统启动以来产生的节拍总数。启动时内核将该变量初始化为0;

此后每次时钟中断处理程序增加该变量的值。每一秒钟中断次数HZ,jiffies一秒内增加HZ。系统运行时间 = jiffie/HZ.

jiffies用途:计算流逝时间和时间管理

jiffies内部表示:

              extern u64 jiffies_64;

              extern unsigned long volatile jiffies;     //位长更系统有关32/64

  32位:497天后溢出

  64位:……

      

复制代码
//0.5秒后超时

unsigned long timeout = jiffies + HZ/2;
……

//注意jiffies值溢出回绕用宏time_before 而非 直timeout > jiffies
if(time_before(jiffies,timeout)){

       //没有超时
}else{

       //超时
}
复制代码

 

四 硬时钟和定时器

  两种设备进行计时:系统定时器和实时时钟。

实时时钟(RTC):用来持久存放系统时间的设备,即便系统关闭后,靠主板上的微型电池提供电力保持系统的计时。

    系统启动内核通过读取RTC来初始化墙上时间,改时间存放在xtime变量中。

系统定时器:内核定时机制,注册中断处理程序,周期性触发中断,响应中断处理程序,进行处理执行以下工作:

  l  获得xtime_lock锁,访问jiffies和更新墙上时间xtime;

  l  更新实时时钟;

  l  更新资源统计值:当前进程耗时,系统时间等;

  l  执行已到期的动态定时器;

  l  执行scheduler_tick()

 

复制代码
//中断处理程序    
irqreturn_t timer_interrupt(int irq, void *dev)
{
    //ticks have passed
    long nticks;

    xtime_update(nticks);

    while (nticks--)
           update_process_times(user_mode(get_irq_regs()));

    return IRQ_HANDLED;
}
 

void xtime_update(unsigned long ticks)
{
    //seq锁
    write_seqlock(&xtime_lock);

    do_timer(ticks);

    write_sequnlock(&xtime_lock);
}

void do_timer(unsigned long ticks)
{
    jiffies_64 += ticks;

    //更新墙上时间 ——实际时间
    update_wall_time();

    calc_global_load(ticks);
}

 

void update_process_times(int user_tick)
{
    struct task_struct *p = current;

    //计算当前进程执行时间
    account_process_tick(p, user_tick);

    //触发软中断TIMER_SOFTIRQ 超时的timer
    run_local_timers();

    //计算进程时间片
    scheduler_tick();

}
复制代码

 

五 定时器

       定时器:管理内核时间的基础,推后或执行时间执行某些代码。

定时器数据结构:

复制代码
struct timer_list {
              struct list_head entry;

              //定时值基于jiffies
              unsigned long expires;

              //定时器内部值
              struct tvec_base *base;

              //定时器处理函数
              void (*function)(unsigned long);

              //定时器处理函数参数
              unsigned long data;

              ……
       };
复制代码

 

定时器使用:

复制代码
    struct timer_list my_timer;

       //初始化定时器
       init_timer(&my_timer);

       ……
      
       //激活定时器
       add_timer(&my_timer);


       //删除定时器
       del_timer(my_timer);

       ……
复制代码

 

六 延迟执行

       使用定时器和下半部机制推迟执行任务。还有其他延迟执行的机制:

忙等待:

       利用节拍,精确率不高

       unsigned long delay = jiffies + 2*HZ ; //2秒 节拍整数倍才行;

       while(time_before(jiffies,delay))

              ;

短延迟:延迟时间精确到毫秒,微妙;短暂等待某个动作完成时,比时钟节拍更短;依靠数次循环达到延迟效果。

       void udelay(unsigned long usecs)

       void mdelay(unsigned long msecs)

 

schedule_timeout()延迟:使执行的任务睡眠指定时间,达到延迟

 

复制代码
signed long __sched schedule_timeout(signed long timeout)
{
       struct timer_list timer;
       unsigned long expire;

       switch (timeout)
       {
         case MAX_SCHEDULE_TIMEOUT:

              //无限期睡眠
              schedule();
              goto out;
         default:
              if (timeout < 0) {
                     current->state = TASK_RUNNING;
                     goto out;
              }
       }
       //超时时间
       expire = timeout + jiffies;

       //初始化一个timer定时器 参数current task
       setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);

       __mod_timer(&timer, expire, false, TIMER_NOT_PINNED);

       schedule();

       del_singleshot_timer_sync(&timer);
 
       /* Remove the timer from the object tracker */
       destroy_timer_on_stack(&timer);
       timeout = expire - jiffies;
 
 out:
       return timeout < 0 ? 0 : timeout;
}


static void process_timeout(unsigned long __data)
{
       //唤醒被睡眠的任务
       wake_up_process((struct task_struct *)__data);
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34259232/article/details/85812466

智能推荐

获取大于等于一个整数的最小2次幂算法(HashMap#tableSizeFor)_整数 最小的2的几次方-程序员宅基地

文章浏览阅读2w次,点赞51次,收藏33次。一、需求给定一个整数,返回大于等于该整数的最小2次幂(2的乘方)。例: 输入 输出 -1 1 1 1 3 4 9 16 15 16二、分析当遇到这个需求的时候,我们可能会很容易想到一个"笨"办法:..._整数 最小的2的几次方

Linux 中 ss 命令的使用实例_ss@,,x,, 0-程序员宅基地

文章浏览阅读865次。选项,以防止命令将 IP 地址解析为主机名。如果只想在命令的输出中显示 unix套接字 连接,可以使用。不带任何选项,用来显示已建立连接的所有套接字的列表。如果只想在命令的输出中显示 tcp 连接,可以使用。如果只想在命令的输出中显示 udp 连接,可以使用。如果不想将ip地址解析为主机名称,可以使用。如果要取消命令输出中的标题行,可以使用。如果只想显示被侦听的套接字,可以使用。如果只想显示ipv4侦听的,可以使用。如果只想显示ipv6侦听的,可以使用。_ss@,,x,, 0

conda activate qiuqiu出现不存在activate_commandnotfounderror: 'activate-程序员宅基地

文章浏览阅读568次。CommandNotFoundError: 'activate'_commandnotfounderror: 'activate

Kafka 实战 - Windows10安装Kafka_win10安装部署kafka-程序员宅基地

文章浏览阅读426次,点赞10次,收藏19次。完成以上步骤后,您已在 Windows 10 上成功安装并验证了 Apache Kafka。在生产环境中,通常会将 Kafka 与外部 ZooKeeper 集群配合使用,并考虑配置安全、监控、持久化存储等高级特性。在生产者窗口中输入一些文本消息,然后按 Enter 发送。ZooKeeper 会在新窗口中运行。在另一个命令提示符窗口中,同样切换到 Kafka 的。Kafka 服务器将在新窗口中运行。在新的命令提示符窗口中,切换到 Kafka 的。,应显示已安装的 Java 版本信息。_win10安装部署kafka

【愚公系列】2023年12月 WEBGL专题-缓冲区对象_js 缓冲数据 new float32array-程序员宅基地

文章浏览阅读1.4w次。缓冲区对象(Buffer Object)是在OpenGL中用于存储和管理数据的一种机制。缓冲区对象可以存储各种类型的数据,例如顶点、纹理坐标、颜色等。在渲染过程中,缓冲区对象中存储的数据可以被复制到渲染管线的不同阶段中,例如顶点着色器、几何着色器和片段着色器等,以完成渲染操作。相比传统的CPU访问内存,缓冲区对象的数据存储和管理更加高效,能够提高OpenGL应用的性能表现。_js 缓冲数据 new float32array

四、数学建模之图与网络模型_图论与网络优化数学建模-程序员宅基地

文章浏览阅读912次。(1)图(Graph):图是数学和计算机科学中的一个抽象概念,它由一组节点(顶点)和连接这些节点的边组成。图可以是有向的(有方向的,边有箭头表示方向)或无向的(没有方向的,边没有箭头表示方向)。图用于表示各种关系,如社交网络、电路、地图、组织结构等。(2)网络(Network):网络是一个更广泛的概念,可以包括各种不同类型的连接元素,不仅仅是图中的节点和边。网络可以包括节点、边、连接线、路由器、服务器、通信协议等多种组成部分。网络的概念在各个领域都有应用,包括计算机网络、社交网络、电力网络、交通网络等。_图论与网络优化数学建模

随便推点

android 加载布局状态封装_adnroid加载数据转圈封装全屏转圈封装-程序员宅基地

文章浏览阅读1.5k次。我们经常会碰见 正在加载中,加载出错, “暂无商品”等一系列的相似的布局,因为我们有很多请求网络数据的页面,我们不可能每一个页面都写几个“正在加载中”等布局吧,这时候将这些状态的布局封装在一起就很有必要了。我们可以将这些封装为一个自定布局,然后每次操作该自定义类的方法就行了。 首先一般来说,从服务器拉去数据之前都是“正在加载”页面, 加载成功之后“正在加载”页面消失,展示数据;如果加载失败,就展示_adnroid加载数据转圈封装全屏转圈封装

阿里云服务器(Alibaba Cloud Linux 3)安装部署Mysql8-程序员宅基地

文章浏览阅读1.6k次,点赞23次,收藏29次。PS: 如果执行sudo grep 'temporary password' /var/log/mysqld.log 后没有报错,也没有任何结果显示,说明默认密码为空,可以直接进行下一步(后面设置密码时直接填写新密码就行)。3.(可选)当操作系统为Alibaba Cloud Linux 3时,执行如下命令,安装MySQL所需的库文件。下面示例中,将创建新的MySQL账号,用于远程访问MySQL。2.依次运行以下命令,创建远程登录MySQL的账号,并允许远程主机使用该账号访问MySQL。_alibaba cloud linux 3

excel离散度图表怎么算_excel离散数据表格-Excel 离散程度分析图表如何做-程序员宅基地

文章浏览阅读7.8k次。EXCEL中数据如何做离散性分析纠错。离散不是均值抄AVEDEV……=AVEDEV(A1:A100)算出来的是A1:A100的平均数。离散是指各项目间指标袭的离散均值(各数值的波动情况),数值较低表明项目间各指标波动幅百度小,数值高表明波动幅度较大。可以用excel中的离散公式为STDEV.P(即各指标平均离散)算出最终度离散度。excel表格函数求一组离散型数据,例如,几组C25的...用exc..._excel数据分析离散

学生时期学习资源同步-JavaSE理论知识-程序员宅基地

文章浏览阅读406次,点赞7次,收藏8次。i < 5){ //第3行。int count;System.out.println ("危险!System.out.println(”真”);System.out.println(”假”);System.out.print(“姓名:”);System.out.println("无匹配");System.out.println ("安全");

linux 性能测试磁盘状态监测:iostat监控学习,包含/proc/diskstats、/proc/stat简单了解-程序员宅基地

文章浏览阅读3.6k次。背景测试到性能、压力时,经常需要查看磁盘、网络、内存、cpu的性能值这里简单介绍下各个指标的含义一般磁盘比较关注的就是磁盘的iops,读写速度以及%util(看磁盘是否忙碌)CPU一般比较关注,idle 空闲,有时候也查看wait (如果wait特别大往往是io这边已经达到了瓶颈)iostatiostat uses the files below to create ..._/proc/diskstat

glReadPixels读取保存图片全黑_glreadpixels 全黑-程序员宅基地

文章浏览阅读2.4k次。问题:在Android上使用 glReadPixel 读取当前渲染数据,在若干机型(华为P9以及魅族某魅蓝手机)上读取数据失败,glGetError()没有抓到错误,但是获取到的数据有误,如果将获取到的数据保存成为图片,得到的图片为黑色。解决方法:glReadPixels实际上是从缓冲区中读取数据,如果使用了双缓冲区,则默认是从正在显示的缓冲(即前缓冲)中读取,而绘制工作是默认绘制到后缓..._glreadpixels 全黑