- 1、本文档共14页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Lesson9---并发性 TinyOS系统经典PPT教程 教学课件
Lesson9 并发性 异步async。 原子性atomic 。 任务 任务之间的运行是原子性(就像原子一样是不可分割的基本微粒,不可被中断的)。 任务的代码应该尽量简单点:避免其他的执行操作突然接管并修改其中的数据。 然而,中断会突然中断当前的执行过程,并抢占运行 。 异步async 可以在任务之外抢断运行的函数,须用“async”关键字标明:它们相对于任务是异步运行的。 默认情况下,命令和事件函数都是同步的:如果它们不是同步的,就得用“async ”关键字注明(在接口的定义文件里)。 所有的中断处理程序都是异步的,不能在它们的调用代码里包含同步的函数。 在中断处理程序中,执行同步函数的唯一方式是发布任务。一个任务的发布是一个异步的操作,而任务的运行却是同步的。 竞争冲突 问题:如果任务带来了延迟,为什么要使用它呢?为什么不使所有函数都是异步的?原因就是:竞争冲突。 即抢占执行的程序会修改当前计算过程中的变量,导致系统进入一种不一致的状态。 多指令周期的指令被打断其后果更加严重。 假设,如果左边的消息发送代码是异步的,就有可能在条件语句“if(!state)”和作业“state = TRUE”之间有另一个组件插进来也试图发送。但两个同时发送就会出现问题。 编程提示:尽量保持代码同步。只有该代码的时间选择非常重要时,或调用该代码的上级代码的时间选择也很重要时,代码才是异步的。 原子性atomic 中断带来的问题意味着程序需要有一种方式能够在执行一小段代码时不会被其他程序抢占。 NesC语言用atomic(中文意思为原子)语句提供了这种功能。 atomic语句块保证了这些变量的读取与写入都是原子性的。 注意,这并不意味着atomic语句块不会被抢占。 即使是atomic语句块,两个不共用变量的代码片段可以相互抢占对方。 在这个例子里,incrementC(理论上来讲)可以侵犯incrementA不可冒犯的原子性。 但incrementA不能抢占它自身,incrementC也一样。 变量的保护 NesC会检查变量有没有被合理的保护,如果没有就发出警告。 那什么时候对变量提供atomic区域保护?如果是从异步函数访问变量,那它必须得到保护。 nesC编译器的分析具有流动敏感性。这意味着,如果函数没有包含在一个atomic代码块里,但它总是在atomic的代码块里被调用,那编译器就不会发出警告。 Atomic的注意 当你可以自由地播撒atomic代码块来避免数据竞争冲突时,你仍应该小心的处理。 一方面,一个atomic代码块浪费CPU资源,所以要尽量减少atomic代码块。 另一方面,atomic代码块越短,对中断的延迟则越少,从而提高系统的并发性。 atomic代码块运行多久是一个棘手的问题,尤其是当一个组件必须调用另一个组件的时候。 atomic代码块运行时长例子 例如,Atmega128单片机上SPI总线的实现组件有一个资源仲裁者在管理对总线的访问权。仲裁者允许不同的用户请求资源(这里指总线),并在它们被授权时通知它们。 当SPI没有用户时,SPI就把它自己关掉,但如果不调用仲裁者(或复制仲裁者的状态变量),它就不知道什么时候没有用户。 在这种情况下,isUse()命令的调用被期望是非常短的(可能就是读取一个状态变量)。 如果有人连接一个仲裁者,其inUse()命令要耗时1ms,那就会出现问题了。最好尽量减少此类情况。 修改状态变量 atomic代码块最基本的使用是在一个组件里转换状态变量。通常,一个状态的转换可以分成两个阶段, 第1个阶段是修改成一个新的状态; 第2个阶段是执行某些操作。 如果状态变量是用async函数访问的,那就需要使状态的转换原子化(即使用atomic代码块)。 但不需要把整个代码段都放在atomic块里,因为发送一个信息包耗时很长,这会导致整个系统错过中断。 编程提示:保持atomic代码块简短,尽量少用。在atomic代码块里调用到外部组件时要小心处理。 * bool state; async command bool toggle(){ if(state == 0 ) { State=1;Return 1; } if(state == 1) { State=0; Return 0; } } 从state=0开始: Toggle(); State=1; ?interrupt Toggle(); State=0; Return 0; Return 1; Command result_t SendMsg.send …{ If(!state) { State = TRUE; //Send a packet
文档评论(0)