task 的目的
做过界面的编程的同学可能会有这种经历,界面不响应,那,其实程序总是在后台运行,但是后台可能是个for循环,那么界面的点击等事件都不能执行。
在windows界面编程中利用了事件机制来做,维护了事件的队列,然后有一个线程不停的取出事件然后回调注册的事件处理函数,每个事件处理函数必然是短小的,否则会独占处理器太久,其他操作得不到响应。
在Qt中,为了维持对用户的响应,使用的是signal函数,signal函数触发slot的操作,理论上也应该是短小的操作。
在两种机制中,主线程负责ui方面的响应,要不就是把发生的时间记录下来,要不就是直接signal信号出去,然后立即返回。总体的规则是负责ui的线程中不能出现长时间占用cpu的操作。
task的出现和以上情况是一致的,在使用post task
后,函数立即返回,可以执行其他操作,其他组件也可以继续相应用户,所有的task应该是短小的操作,以保证其他的task不会产生太大的延迟。
TinyOS中采用了队列的机制来循环处理task,用线程来讲就好像,由boot触发的main函数像一个主线程,用来记录用户的操作以及各种task,而schedule组件就像是一个负责处理的线程,循环的处理用户已经post的线程,这样,用户的操作,如亮灯、终端等,可以得到及时的响应,外界的信息也不会那么容易的丢失。
task 的机制
在tinyos 1.x中task采用的方式是post task
,在2.x中使用BasicTasic接口来进行task的注册,但完全可以用1.x中的方法。
前面提到过post task
只是往task队列中添加一条task调用记录,然后由scheduler循环处理,在post task
和scheduler真正调用task时,一定会产生延迟,也就是说task的调用是推后的函数调用。
因为在1.x中schedular貌似没有设置task队列的长度,那么意味着一个组件可以无限post task
,但实际上这种情况会使得一个组件独占cpu资源。
为了避免这种情况,在2.x中schedular设置了的task的调用数组,数组中的每一项是注册过的task,当task被调用了,就相应的置位,关于顺序问题应该是有做记录(我不知道,求告诉QAQ),这样可以防止一个组件post过多相同的task独占资源。
task 和函数的不同
执行操作不同
最主要的不同在于调用,这也是task存在的意义,就像前面说的,task是为了相应用户而生,调用 task 时在 post 后立即返回,而函数要执行完后返回。
长相也不同
task的标准形式如下
task void 函数名()
{
// do task
}
这意味着task没有返回值,也没有参数。task的思想是为了执行一段操作,调用task时立即返回,所以没有返回值是情理之中,但post task
却有返回值,我们等会说。
task 的参数我的想法是,TinyOS 的思想是节点的内存有限,所以尽可能减少临时变量和动态变量这一类变量,所以可以看到文档建议一些变量最好直接在组件中进行定义,没有那么多的内存空间来做函数的栈存储临时变量。
基于以上分析,task不带参数,也不帮你存储参数,但由于这个性质,task运行时可能会产生问题,我们在后面会说到。
是否允许中断,应该说是抢占?
可以明确的是,task是允许中断(我觉的更确切应该说是抢占)的,我想这也是保持用户响应的一部分。同时,我的想法是普通函数是不允许中断的,因为task是允许中断的。。。
async 函数意味着可以异步执行,TinyOS规定 async 函数中不能调用普通函数,也就是同步函数,异步的意思貌似是可以抢占其他函数的执行,或者说是打断,同时自己也可以被抢占。那么如果想要在 async 函数中执行同步代码,就要用到task,也是唯一方式。
task 返回失败的情况
首先post task
是有返回值的。
为了防止同一组件不停的post task
,Tinyos 2.x中post在有同名task正在队列并且没有执行时返回Fail,应该就是检查task调用数组了,这以为着你开启一个for循环来post数组是不允许的,如下
for (int i = 0; i < 10; i++)
{
post process_message();
}
上面这代码,如果第一个post成功,并且process_message
函数执行有一定时间,那么根据TinyOS规定,一个process_message
在执行,一个process_message
函数在队列,其他的处理函数就都没有得到执行,返回的是Fail。在这种情况下,你的想法是处理10条消息,但实际上只处理了2条。
这样看来,这种情况下你所post task
的数目与实际执行的task的数目并不一定相同。
但TinyOS允许task自身调用,如下
task void process_message()
{
// start processing message
...
// finish processing message
process_message()
}
通过这种方式,task应该是不会返回Fail的,因为task实在结尾处调用自身,如果设置一个counter的话,应该可以实现上面的for循环调用。
In TinyOS 2.x, a basic post will only fail if and only if the task has already been posted and has not started execution.
task 只关注当前
按照线程的思维方式,线程所使用的变量都是进程的,这意味着如果其他线程修改了进行的变量,当前线程可能并不知情。
task执行任务是推迟的,并且task是允许中断的,这意味这在使用post task
后,组件的值随时可能发生变化,任何一个中断都有可能修改数据,你post task
时所认为task使用的变量,当scheduler真正调用时,可能已经物是人非。
task执行时永远使用当前组件内最新(updated)的变量值,这意味着你在post task
时最好想清楚当task执行时所采用的组件变量是否已经发生改变,必要的话需要采取一定保护变量的措施,如设置变量标志位等,如使用send时采用send_busy标志应该是常用的方法。
其他
我看到 TaskBasic 接口里好像有优先级的设定,这意味着如果加入优先级, task 的顺序可能会发生不可控的变化,使用 task 时需要更为细致。
最后
作者水平有限,准确信息请参考TinyOS官方文档
TinyOS 中的 task的更多相关文章
-
(转).NET 4.5中使用Task.Run和Parallel.For()实现的C# Winform多线程任务及跨线程更新UI控件综合实例
http://2sharings.com/2014/net-4-5-task-run-parallel-for-winform-cross-multiple-threads-update-ui-dem ...
-
Ext.Net中的Task控件的使用
在用到Ext.Net中的Task控件的时候,写了一下基本的使用方法: 控件是在TaskManager里面的Tasks下面的Task 此控件的常用属性有,TaskID.Interval(设置间隔时间). ...
-
SSIS中Sql Task 获取系统变量
原文:SSIS中Sql Task 获取系统变量 执行 SQL 任务使用不同的连接类型时,SQL 命令的语法使用不同的参数标记.例如,ADO.NET 连接管理器类型要求 SQL 命令使用格式为 @var ...
-
Linux中的task,process, thread 简介
本文的主要目的是介绍在Linux内核中,task,process, thread这3个名字之间的区别和联系.并且和WINDOWS中的相应观念进行比较.如果你已经很清楚了,那么就不用往下看了. LINU ...
-
Proxmox VE中出现TASK ERROR: command &#39;apt-get update&#39; failed: exit code 100的解决方法
问题描述: 出现这个错误一般在WEB或者在Proxmox VE的服务器上面能看到日志: PVE中出现TASK ERROR: command 'apt-get update' failed: exit ...
-
Android中的task和stack
今天在重新理了一遍intent的过程中发现task是一个神奇的东西,而它又和stack有着很深的联系.task顾名思义是一个任务,但是这个任务可不一定只是来自一个app,比如我用微信来发一张图片,那么 ...
-
SV中的task和function
SV中class的properties和methods默认都是public的,但是可以声明为local和protected. 一个properties声明为local类型的,则只在该class中的me ...
-
swoole中使用task进程异步的处理耗时任务
我们知道,swoole中有两大进程,分别是 master 主进程和 manager 管理进程. 其中 master 主进程中会有一个主 reactor 线程和多个 reactor 线程,主要的作用就是 ...
-
深入理解gradle中的task
目录 简介 定义task tasks 集合类 Task 之间的依赖 定义task之间的顺序 给task一些描述 task的条件执行 task rule Finalizer tasks 总结 深入理解g ...
随机推荐
-
OWIN的理解和实践(一) – 解耦,协作和开放
概述 OWIN的全称是Open Web Interface For .Net, 是MS在VS2013期间引入的全新的概念, 网上已经有不少的关于它的信息, 这里我就谈下我自己的理解: OWIN是一种规 ...
-
ucos操作系统的内核有哪些调度方法
1)时间片轮番调度法 假设系统中有5个任务,T1,T2,T3,T4,T5,这个时候,操作系统为每一个任务分配时间,比如说我们为T1任务分配10毫秒,为T2任务分配20毫秒,为T3任务分配5毫秒,为T4 ...
-
python 接口开发(一)
cmd中,提示pip版本太低,先升级pip pip install --upgrade pip (pip,安装和管理python扩展包的工具) cmd下,pip,出现详细信息证明装成功了 pip ...
-
iOS开发之静态库.a的制作教程
第一种方法:直接新建一个工程. 1.新建项目-> 选择 “Cocoa Touch Static Library” 2.添加库需要包含的源代码,将你工程里的代码添加到打静态库工程里: 3.配置一下 ...
-
WebBrowser控件的高级定制+mshtml
--> blog:WebBrowser控件的高级定制---以下为三篇重要的参考文献, 第一篇可以禁用了js弹窗和声音 第二篇的引用文献禁用了IE弹窗,但是原文的说明很好 第3篇 ...
-
转:搭建Hive的图形界面
原文来自于:http://blog.csdn.net/w13770269691/article/details/17353595 今天想使用一下Hive的图形化工具HWI,我的Hive是0.12.0版 ...
-
C语言文件详解
1.C语言FILE类,在stdio.h头文件中,FILE类是一个结构体:定义如下: 通过typedef定义了 文件类型 的别名: “FILE”,这样以后需要读写文件的时候直接定义FILE就行了. ...
-
CSS元素垂直居中方法总结
坚持,坚持,坚持... 以上为自我鼓励,哈哈... ------------------------------------------------- 相信没有真正是尝试过的人应该都和我一样,觉得居中 ...
-
Drools文档(六) 用户手册
用户手册 基础 无状态的知识Session Drools规则引擎拥有大量的用例和功能,我们要如何开始?你无须担心,这些复杂性是分层的,你可以用简单的用例来逐步入门. 无状态Session,无须使用推理 ...
-
override与重载(overload)的区别
重载是相同函数名字.参数或参数类型不同,进行多次承载以适应不同的需要.(orerload)是面向过程的重载. (override)是面向对象的重载.是进行基类中的函数重写.