首先聊一聊全局变量:

在慕课上学习浙大老师的C语言课程的时候,翁恺老师一直在强调在程序中我们要避免使用全局变量,C语言的程序员(尤其像我这样的野生程序员)为了方便,经常会不顾这个编码规范。全局变量有一些显而易见的好处:全局可见,内存地址固定,读写效率高。比起优点来,全局变量的槽点更多:1)学过面向对象语言的同学会更加谨慎的使用全局变量,这破坏了函数的封装性能,降低了函数的可移植性。2)使代码可读性差,大型程序里面简直是灾难  3)生存期长,会占用较多的内存单元。
 
最近在看一本书叫《信息系统设计与分析》,里面从软件工程的角度也阐述了全局变量的危害。优秀的软件设计应尽可能达到高内聚低耦合。
内聚是指一个模块各个元素间彼此结合的紧密程度。
耦合是指模块之间互相连接的紧密程序。(关于这个话题,可以看一下其他博主的博文)全局变量毫无疑问会增加系统的耦合度。因此,这也是我们慎用全局变量的理由

ucos中需要注意的全局变量:

从裸机到ucos需要深刻转换的一点是ucos是一个可剥夺型的多任务内核,这意味着ucos总是执行当前优先级最高的就绪任务。全局变量生存期从程序执行到结尾,作用域是从变量定义开始到源文件结束。这意味着在ucos这样的可剥夺式的系统中,必须保障对全局变量的独占式访问。否则,有可能会出现任务间的竞争和数据破坏。

在《嵌入式实时操作系统ucos3》中举了一个关于时间更新的例子很有力的说明了全局变量在任务切换时不做保护带来的隐患:

u8 Seconds;
u8 Minutes;
u8 Hours;
void TimeOfDay(void *p_arg)
{
(void)p_arg;
OS_ERR err; while (DEF_TRUE) { /* Task body, always written as an infinite loop. */ OSTimeDlyHMSM(, , , ,
OS_OPT_TIME_HMSM_STRICT,
&err);
Seconds++;
if(Seconds > )
{
Seconds = ;
Minutes++;
if(Minutes > )
{
Minutes = ;
Hours++;
}
if(Hours > )
{
Hours = ;
}
}
}
}

假如在模块执行完Minutes = 0;这一行代码时,一个中断发生了,并使得一个具有比void TimeOfDay(void *p_arg)更高优先级的任务进入了就绪表,那么在中断结束返回后,TimeOfDay()就会被这个更高优先级的任务抢占而无法继续运行。一旦高优先级的任务想要从时钟模块中获取时间,那么由于中断前时钟模块的小时值没有更新,那么所读到的将会是一个与正确时间相差整整一个小时的错误值。

这里的时钟模块就是一个共享资源,在ucos中必须对此加以保护,保证对共享资源的独占访问。

PS:以上ucos部分的内容皆来自于《嵌入式实时操作系统uc/OS-III》一书的第十三章

ucos中需要注意的全局变量的更多相关文章

  1. ucos中的三种临界区管理机制

    熟悉ucos,或者读过Jean.J.Labrosse写过的ucos书籍的人,一定会知道ucos中著名的临界区管理宏:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(). 同样 ...

  2. C/C++中static的用法全局变量与局部变量

    1.什么是static? static 是C/C++中很常用的修饰符,它被用来控制变量的存储方式和可见性. 1.1static的引入 我们知道在函数内部定义的变量,当程序执行到它的定义处时,编译器为它 ...

  3. ucos中信号量 事件标志 消息队列都怎么用

    信号量 事件标志和消息队列分别应用于什么场景(反正我学的时候有点闹不清,现在总结一下): 信号量和事件标志用于任务同步.详细来说,这个功能可以替代以前裸机中你打一个标记的功能,比如使用了一个定时器,5 ...

  4. python开发_python中的变量:全局变量和局部变量

    如果你在为python中的变量:全局变量和局部变量头疼,我想这篇blog会给你帮助 运行效果: 代码部分: #Python中的变量:全局变量和局部变量 #在很多语言中,在声明全局变量的时候,都喜欢把全 ...

  5. [Taro] taro中定义以及使用全局变量

    taro中定义以及使用全局变量 错误的姿势 // app.tsx文件中 class App extends Component { componentDidMount() { this.user = ...

  6. SQL Server中,常用的全局变量

    在SQL Server中,全局变量是一种特殊类型的变量,服务器将维护这些变量的值.全局变量以@@前缀开头,不必进行声明,它们属于系统定义的函数.下表就是SQL Server中一些常用的全局变量. 全局 ...

  7. Javascript中的局部变量、全局变量的详解与var、let的使用区别

    前言 Javascript中的变量定义方式有以下三种方式:1.直接定义变量,var与let均不写: a = 10; 2.使用var关键字定义变量 var a = 10; 3.使用let关键字定义变量 ...

  8. UCOS 中的中断处理

    最近遇到一个问题,当我在UCOS里调用系统延时"OSTimeDlyHMSM(0, 0, 0, 10)",程序进入硬件错误中断“HardFault_Handler”中. 我开始以为是 ...

  9. ucos中消息队列的应用(二)

    继续说任务间的通信. 本次的任务是在ISR中发送一个消息给任务,ucos的代码中的是非常之简洁和容易理解啊.创建,释放,等待,非常好理解,不再赘述. 说说我遇到的问题,数据帧接收完之后,向消息队列发送 ...

随机推荐

  1. TypeScript安装备忘:npm proxy设置

    如果使用了代理网络,因为npm无法自动识别Internet代理,则需要手动设置npm代理才能下载包. 设置命令:    npm config set proxy http://proxyhost:pr ...

  2. Centos 7 64位 minimal 最小化安装的系统中静默安装oracle 11g r2

    1:安装好centos 7 操作系统: 虚拟机安装centos 7,在vmware中一步步来就可以成功. 2:安装vim 最小化安装的系统只有vi编辑器,这里装一下vim,个人习惯,可以不安装, 那么 ...

  3. java-消息中间件-基于内存的mq

    如果用户的请求比较费时,可以考虑将用户的请求信息放到队列中,立即返回给用户处理中等信息,这样可以给用户比较流畅的体验,后端可以利用单独的服务消费消息,做到了解耦,提高了并发能力. 本文使用jdk为我们 ...

  4. 如何以system身份运行指定的程序?

    Local System(本地系统)是Windows操作系统内置的特殊账户.它拥有比Administartor更高的权限.smss.exe(会话管理器).csrss.exe(客户端/服务器运行时子系统 ...

  5. tomcat安装启动之后localhost:8080页面进不去,提示错误500

    具体的错误展示页面如下: 首先,需要考虑到是不是安装的tomcat版本和自己安装的jdk的版本一致,如果不一致,建议将tomcat换成和jdk一致或者高于jdk版本的tomcat版本.(比如安装的jd ...

  6. Windows10最新更新破坏了PowerShell功能

    Java9%E6%8E%A5%E8%BF%91%E4%BA%A4%E4%BB%98%E6%97%A5%E6%9C%9F%E5%92%8C%E8%8C%83%E5%9B%B4%E5%AE%A1%E6%9 ...

  7. linux命令--xargs的使用

    xargs 是给命令传递参数的一个过滤器,也是组合多个命令的一个工具. xargs 可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据. xargs 也可以将单行或多 ...

  8. POI导入具有合并了单元格的Excel

    POI进行单行单行地导入的数据在网上有许多的文章,但是要导入一个具有合并单元格的excel貌似比较难找.刚好最近完成了这样的一个需求,要求导入具有合并单元格的excel: /** * 读取excel数 ...

  9. part1

    一.hello world 明确的指出 hello.py 脚本由 python 解释器来执行.coding:utf-8处理脚本中的中文 #!/usr/bin/env python # _*_ codi ...

  10. idea的环境设置

    IDEA的个人配置与常用操作 IDEA的个人配置 1.修改代码编辑器 新版的IDEA默认使用vim编辑器(linux下的一个工具),虽然熟练掌握后可以提高工作效率,但是学习成本很大,不习惯的可以选择关 ...