让你提前认识软件开发(21):C程序中的定时器

第1部分 重新认识C语言

C程序中的定时器

 

【文章摘要

        在实际的C程序中,一个模块执行多个操作是很常见的事情。如果多个操作同时进行,会出现程序效率低下、计算机CPU占用率过高等情况,这时就需要对所有操作的执行顺序作一个合理的安排,这就涉及到定时器的使用。

        本文对C程序中的定时器的类型、设置和清除方法等作了详细的介绍,为相关开发工作的开展提供了参考。

【关键词

        C程序  定时器  操作  开发

 

一、定时器的定义及分类

        我们所熟悉的定时器是一个多任务定时提醒的软件,安装于电脑或手机上。举个例子,我们经常用的闹钟其实就是定时器,它会在我们设定的时间运行某种程序,在其它时间则处于休眠状态。

        那么什么是C程序中的定时器呢?C程序中的定时器是程序员编写的用于定时执行某种操作的程序,是相关C代码的集合。这个定时器是“幕后的英雄”,我们能够看到的是软件所体现出来的某项功能,而看不见的是定时器所起的作用。

        根据所起的作用的不同,C程序中的定时器分为如下两类:

        第一类,在多个操作中设定不同操作执行顺序的定时器。在一个很大的软件模块中,同时进行多个操作会降低程序的执行效率,合理地使用定时器能够让某些操作避开程序执行的“高峰期”,达到舒缓程序执行压力的作用。这时的定时器所起的作用和在上下班时间十字路口的红绿灯的作用类似。

        第二类,用于限制某种操作的执行时间,若在规定时间内没有执行该操作则作超时处理的定时器。这类定时器多用于需要和其它模块进行通信的模块中。如果一个模块向其它模块发了一个很重要的消息,需要等到其它模块答复后才能进行下一步的操作,那么定时器就在这个时候派上用场了。可以在定时器中设定本模块所能“容忍”的其它模块最迟应答的时间,如果超过了这个时间,则认为对方无应答,直接进行后续操作。

       在C程序中,合理利用定时器,可提高程序的执行效率,同时可让程序体现出逻辑层次感和严密性。

 

二、定时器的数据结构

       为了完成功能,一个典型的定时器的数据结构如下:

// 先重定义基本数据类型

typedef unsigned char        UINT8;

typedef unsigned short int  UINT16;

typedef unsigned int           UINT32;

 

// 定时器的数据结构

typedef struct

{

    ……

    ……

    UINT8   iUseFlag;            // 该定时器是否正在使用

    UINT8   iArrivedFlag;       // 使用该定时器的时间是否已到

    UINT8   iTimerType;         // 该定时器的类型

    UINT16  iModuleNo;         // 使用该定时器的模块号/进程号等信息

    UINT32  iSetTime;            // 设定该定时器的启动时间, 即相对此刻, 该定时器在多长时间之后启动

    UINT8   iTimerNo;            // 该定时器的编号

    UINT8   iQue;                  // 该定时器的存放队列

    UINT16  iQuePrev;          // 该定时器的存放位置的前一个结点

    UINT16  iQueNext;          // 该定时器的存放位置的后一个结点

    ……

    ……

} TimerStruc_T;

 

        一个定时器结构体所包含的字段根据不同软件产品和项目组的要求而略有区别,但如上面结构体中罗列出来的字段都是需要的。字段的含义见对应字段后面的注释。

 

三、如何设置和清除定时器

3.1 设置定时器的流程

        在实际的软件开发项目中,一般将设置定时器的流程封装为函数。在需要设置定时器的时候,只需要调用该函数即可。

        设置定时器的流程如图1所示。

图1 设置定时器的流程

 

        有关此流程的说明如下:

        (1) 在设置定时器之前,先要判断该定时器是否正在使用。如果在使用中,那么要先清除定时器以释放资源。这是为了防止一个定时器有多种用途的情况。

        (2) 在获取定时器存放资源之前,要对初始化及信息入队操作进行加锁处理。为了防止同样的资源被多个定时器获得。

 

3.2 清除定时器的流程

        清除定时器的操作同样会被封装为函数。在需要清除定时器的时候,只需要调用该函数即可。

        清除定时器的流程如图2所示。

图2 清除定时器的流程

 

        有关此流程的说明如下:

        (1) 在清除定时器之前,先要判断该定时器是否正在使用及清除时间是否达到。如果两者中有一个不满足,则不用清除定时器。

        (2) 在清除定时器相关信息之前,为了保持操作的唯一性,同样要进行加锁处理。

 

四、总结

        随着程序功能的日益完善和丰富,不同操作执行顺序越发显得重要,这就为定时器提供了施展才能的“舞台”。

        本文以作者的实际项目开发工作为背景,对C程序中的定时器的类型、设置和清除方法等作了详细的描述,为相关模块的设计和程序的编写提供了有益的参考。

 

 

 

(欢迎访问南邮BBS:http://bbs.njupt.edu.cn/)
(欢迎访问重邮BBS:http://bbs.cqupt.edu.cn/nForum/index)

(本系列文章每周更新两篇,敬请期待!本人微博:http://weibo.com/zhouzxi?topnav=1&wvr=5,微信号:245924426,欢迎关注!)

时间: 2024-11-01 16:07:42

让你提前认识软件开发(21):C程序中的定时器的相关文章

提前认识软件开发(14):程序中的算法

算法(Algorithm),是程序的灵魂.著名计算机科学家.图灵奖获得者沃思曾提出过一个公式:数据结构+算法=程序.可见,算法在程序中占有非常重要的地位. 在实际的软件开发项目中,不管是有意设计或是无意为之,我们几乎随时在和算法打交道.小到定义一个变量,大到编写一个函数,这些都是算法的实现过程. 本文以作者实际项目工作为背景,介绍算法在C程序中的应用. 1.算法概述 什么是算法呢?先来看一看一些计算机书籍中的定义. 经典书籍<算法导论>(Cormen等著,机械工业出版社)中,作者认为算法是一系

让你提前认识软件开发(15):程序调试的利器—日志

第1部分 重新认识C语言 程序调试的利器-日志           如果世界上有一个人能够保证一次写出来的代码是百分之百正确的,那么毫无疑问,他一定是世界上最优秀的程序员,没有之一.为什么要求代码写好过后要进行充分的自测(包括单元测试和集成测试)?就因为是人皆会犯错,是程序就会有bug.作为一名软件开发人员,必须要学会对程序进行测试,也就是要学会程序的调试.          一般而言,对代码的调试有以下几种方法:         第一,凭肉眼看.在开发阶段,我们编写的每一行代码都需要用我们的"

让你提前认识软件开发(6):程序的版式和注释

第1部分 重新认识C语言 程序的版式和注释            在<高质量程序设计指南(C/C++语言)>中,作者说:可以把程序的版式比喻为"书法",好的"书法"可以让人对程序一目了然,看得兴致勃勃.确实,我们一打开程序,首先看到的便是程序的排版,我们的第一印象便是程序写得是工整还是凌乱.都说第一印象很重要,为了给大家留下好的第一印象,我们一定要注重程序的版式.         此外,好的注释能够帮助读者更快地理解程序,提高工作的效率.也许是因为工作比

提前认识软件开发(6):程序的版式和注释

第1部分 重新认识C语言 程序的版式和注释 在<高质量程序设计指南(C/C++语言)>中,作者说:可以把程序的版式比喻为"书法",好的"书法"可以让人对程序一目了然,看得兴致勃勃.确实,我们一打开程序,首先看到的便是程序的排版,我们的第一印象便是程序写得是工整还是凌乱.都说第一印象很重要,为了给大家留下好的第一印象,我们一定要注重程序的版式. 此外,好的注释能够帮助读者更快地理解程序,提高工作的效率.也许是因为工作比较忙的缘故,很多软件工程师不喜欢为自己

提前认识软件开发(22) shell脚本中的文件操作

编写shell脚本时,经常会涉及到对文件的操作,比如从文件中读取一行数据.向文件追加一行数据等.完成文件读写操作的方法有很多,了解各种命令下文件操作的执行情况,有助于开发人员在不同使用场景下选择合适的命令. 本文以实际的shell脚本为例,介绍了对文件进行操作的不同方法,为相关开发工作提供了参考. 一.概述 在某些软件项目的需求文档中,要求程序一次性读或写的数据规模较大,可达1000万行级,这就涉及到对程序执行方法和效率等的考虑. 本文比较了不同shell命令在对文件进行读或写操作过程中执行效率

提前认识软件开发(31) 数据库脚本中的begin与end

在数据库脚本中,begin与end是一对奇怪的单词.缺少它们,某些代码看起来会让人一头雾水:添加它们,代码的结构瞬间就清晰了. 确实,begin与end作为代码语句的开始和结束标志,可以让脚本程序的逻辑明确,易于阅读. begin与end主要用在以下地方: 1. if.else.else if.while等语句中 if.else.else if.while等语句要自占一行,执行语句不得紧跟其后,不论执行语句有多少都要加语句块标志begin-end. 脚本文件中的begin和end应独占一行并且位

提前认识软件开发(30) 数据库脚本中的空行与空格

在数据库脚本中,空行与空格起着"锦上添花"的作用.恰当地使用它们,可以提高代码的规范性及可阅读性,进而提升数据库的编程效率. 1. 空行 空行起着分隔脚本段落的作用,适当的空行可以使脚本的布局更加的清晰.空行的作用有以下几个: (1) 用于分隔两个数据表的创建脚本 示例: create table tb_example1 ( [表内容实现代码] ) go -- 空行 create table tb_example2 ( [表内容实现代码] ) go (2) 用于分割两个存储过程的创建脚

提前认识软件开发(28) 数据库存储过程中的重要表信息的保存

1. 存储过程中的重要表信息的保存 在很多存储过程中,会涉及到对表数据的更新.插入或删除等,为了防止修改之后的表数据出现问题,同时方便追踪问题,一般会为一些重要的表建立一个对应的debug表.这个debug表中的字段要包括原表的所有字段,同时要增加操作时间.操作码和操作描述等字段信息. 例如,在某项目中,包括了如下一个重要的表tb_XXX: create table tb_XXX ( AAA varchar(30) not null, -- AAA BBB varchar(30) not nul

提前认识软件开发(1) 序言

序言 正式踏上软件开发岗位已经将近两年了,经历了很多,也学到了很多."万事开头难",学生转变为职业人的过程,恰似茧化成蝶的过程. 1.为什么要写作本系列? 在工作的过程中,我发现我们在学校里面学到的很多东西片面肤浅,根本达不到岗位的要求.像编码规范.研发流程等等学校里几乎不提及的知识,在实际的软件开发项目中却恰恰是异常的重要. 在学校里面,我们欠缺的教育主要包括以下方面: 第一,对编码规范的要求.计算机编程课上,老师只要求学生能够编写程序实现既定的功能即可,几乎不会对编码规范提出要求,