搜索
bottom↓
回复: 29

《时间触发》这本书提供的调度器最大的缺点

[复制链接]

出0入0汤圆

发表于 2014-4-8 23:12:28 | 显示全部楼层 |阅读模式
《时间触发》这本书提供的调度器,最大的缺点是程序之间缺少信息沟通

比如如下程序,是一个调度函数
/********************************************************
      ×××××××××××××××调度函数×××××××××××××××××
********************************************************/

void OS_Dispatch_Tasks(void)

     {uchar Index;
      for (Index=0;Index<OS_MAX_TASKS;Index++) //在任务队列中循环找
           {if(OS_tasks_G[Index].RunMe>0)      //如果某个任务需要运行
              { (*OS_tasks_G[Index].pTask)();  //就运行这个任务
                OS_tasks_G[Index].RunMe-=1;    //运行当量减一

                if(OS_tasks_G[Index].Period==0)//如果周期等于0
                  {OS_Delete_Task(Index);      //删除此任务
                  }
              }
           }                           
      OS_Report_Status();  //报告系统状态
     // OS_Go_To_Sleep();    //进入空闲模式     
     }

其中有一条是删除函数程序:OS_Delete_Task(Index);      //删除此任务
这个程序只是单纯的删除函数,函数退出时,并没有清理函数内部的变量,这样当再次运行函数时,由于前一次变量没有清理干净,会发生运行错误的。

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2014-4-8 23:18:57 | 显示全部楼层
这就好比手机上的安卓软件,如果你从运行程序当中直接按,强行停止程序,虽然程序停止了,但是会发生错误,比如,金山电池医生,强行停止,通知栏上的电池电量图标会永久停在通知栏上,而且电量也不再下降了,因为程序停止了。
而,如果在 全部程序界面,点清除金山电池医生内存,这时金山电池医生就停止运行,同时所有内存也清除,不会发生错误了。

出0入0汤圆

 楼主| 发表于 2014-4-8 23:25:30 | 显示全部楼层
我看如下 方法可能会好
(*OS_tasks_G[Index].pTask)();  //就运行这个任务
这条程序会面加一个参数,变成:(*OS_tasks_G[Index].pTask)(OS_tasks_G[Index].stop);  //就运行这个任务
这样在程序中判断,如果是stop==1,就清除内存,并且删除本函数。

出0入0汤圆

发表于 2014-4-8 23:25:52 来自手机 | 显示全部楼层
期待激烈讨论

出0入0汤圆

 楼主| 发表于 2014-4-8 23:35:08 | 显示全部楼层
写这本书的作者号称这是非常安全的 程序框架,
经过我的使用发现,如果避开上面提到的缺点,的确是不错,但是,很多时候我们没有办法避开这种应用,那么程序会发生 未知的 不确定的 偶然性的错误。关于这些 作者没有过多的说明,我自己也没有发现有什么更好的方法来解决。
可能,使用RTOS系统可以改变这一缺点吧,因为,这个系统任务间据说有信息传递机制。
而《时间触发》是使用了一种叫做任务队列的方法,这种方法从外部很难动用程序内部的数据。程序指针。

出0入0汤圆

 楼主| 发表于 2014-4-8 23:40:20 | 显示全部楼层
另外还有一种方法可以
就是添加一个程序,这个程序只运行一次,然后在这个添加程序里面再次添加两个程序,第一个只运行一次,作用是初始化,设置好内存数值,第二个才是实际程序

出0入0汤圆

发表于 2014-4-9 00:08:38 | 显示全部楼层
可重入。。。

出0入0汤圆

 楼主| 发表于 2014-4-9 05:48:00 | 显示全部楼层
本帖最后由 zhwm3064 于 2014-4-9 05:51 编辑


就是尽量使用局部变量,使用局部变量一定是可重入的(可中断的)
如果使用全局变量 或者静态变量,就要想出种种的方法,目的是重入时,不能出错。

实际上我在6楼提供的方法就是只使用局部变量,分两个程序,头一个程序只调用一次,比如设置IO等操作,第二个程序才是主程序,这样两个程序都不包含静态变量。如果合为一个程序,必然得使用静态变量

出0入264汤圆

发表于 2014-4-9 08:02:49 | 显示全部楼层
需要自己动手修改一下,增加任务之间的通信,可以采用队列或者事件的方式。

出0入0汤圆

发表于 2014-4-9 08:08:37 来自手机 | 显示全部楼层
说的有些道理

出0入0汤圆

发表于 2014-4-9 08:12:21 | 显示全部楼层
本帖最后由 coleyao 于 2014-4-9 16:25 编辑

如果任务一直运行不删除呢,如果需要任务停止一段时间可以挂起,等需要时再唤醒就好了!  

出0入0汤圆

发表于 2014-4-9 08:23:57 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2014-4-9 09:03:09 来自手机 | 显示全部楼层
一般来说,主要程序之间具有互斥性,所以,可以设置一个全局互斥变量,这样程序相互切换,根据互斥变量的值来确定该停哪个程序该开那个程序,这样就会好了。

出0入8汤圆

发表于 2014-4-10 16:36:45 | 显示全部楼层
这是非常老的一本书吧。好像很多年前看过。书写的非常简单。

出0入0汤圆

发表于 2014-4-10 18:10:22 来自手机 | 显示全部楼层
书上的内容是不复杂,讲的东西却很实用,而且提供实例和源代码,实时os入门首选啊!

出0入0汤圆

发表于 2014-4-11 22:57:54 | 显示全部楼层
好贴》》》》》》》》》》》》》》》

出0入0汤圆

发表于 2014-6-5 09:03:45 | 显示全部楼层
这本书从传统的while(1)到理解任务调度入门的好书

出0入0汤圆

发表于 2014-6-5 09:22:41 | 显示全部楼层
别人讲的就是调度器,提供的是一种思路,一种方法,怎么用?还是要自已把握

出0入0汤圆

发表于 2014-6-5 09:32:19 | 显示全部楼层
批处理系统而已

出0入0汤圆

发表于 2014-6-7 11:29:23 | 显示全部楼层
我就只创建不删除

出0入0汤圆

 楼主| 发表于 2014-6-7 16:25:45 来自手机 | 显示全部楼层
我看书上提供的例程全部是只添加程序,而且是一次性添加完,不删除。而我是随时添加随时删除,任务数量是动态的。现在所遇到的问题是——有些任务是不可以任意删除的,必须处理任务中的变量。这个可以实现,但是估计比较复杂,由于任务自身不可以结束自身,所以,涉及到任务与调度器之间的多次通信。1调度器发信息,指示需清除变量,2任务中清变量,并返回信息。3调度器收到信息,结束任务4调度器确认任务已结束,再添加另一任务   或者使用公用变量区,结束任务时同时清变量

出0入0汤圆

发表于 2014-6-12 12:39:37 | 显示全部楼层
函数内部的局部变量不存在这种问题吧,你退出函数变量就不存在了。如果是静态变量或者全局变量,那你用别的OS同样存在可重入问题,都是要留意的。

出0入0汤圆

发表于 2014-6-12 12:50:09 | 显示全部楼层
为毛你的任务不会自己初始化自己的运行环境?
难道你打算拿个变量不初始化就用?

出0入0汤圆

发表于 2014-9-16 15:37:42 | 显示全部楼层
mangocity 发表于 2014-6-12 12:50
为毛你的任务不会自己初始化自己的运行环境?
难道你打算拿个变量不初始化就用? ...

LS正解。。。

出0入0汤圆

发表于 2014-9-20 23:55:59 | 显示全部楼层
期待讨论

出0入0汤圆

发表于 2014-9-25 13:36:38 来自手机 | 显示全部楼层
长知识了。谢谢

出50入0汤圆

发表于 2014-9-25 13:49:26 | 显示全部楼层
学习了,这样的讨论交流最实用

出0入0汤圆

发表于 2014-10-14 17:33:49 | 显示全部楼层
看了一点里面的程序,如下:

  1. tByte SCH_Add_Task(void (code * pFunction)(),
  2.                    const tWord DELAY,
  3.                    const tWord PERIOD)   
  4.    {
  5.    tByte Index = 0;
  6.    
  7.    // First find a gap in the array (if there is one)
  8.    while ((SCH_tasks_G[Index].pTask != 0) && (Index < SCH_MAX_TASKS))
  9.       {
  10.       Index++;
  11.       }
  12.    
  13.    // Have we reached the end of the list?   
  14.    if (Index == SCH_MAX_TASKS)
  15.       {
  16.       // Task list is full
  17.       //
  18.       // Set the global error variable
  19.       Error_code_G = ERROR_SCH_TOO_MANY_TASKS;

  20.       // Also return an error code
  21.       return SCH_MAX_TASKS;  
  22.       }
  23.       
  24.    // If we're here, there is a space in the task array
  25.    SCH_tasks_G[Index].pTask  = pFunction;
  26.      
  27.    SCH_tasks_G[Index].Delay  = DELAY;
  28.    SCH_tasks_G[Index].Period = PERIOD;

  29.    SCH_tasks_G[Index].RunMe  = 0;

  30.    return Index; // return position of task (to allow later deletion)
  31.    }
复制代码


我认为,在创建任务的时候,有必要加入原子保护操作

出0入0汤圆

发表于 2014-11-2 21:51:21 | 显示全部楼层
这本书挺好的   

出0入0汤圆

发表于 2014-11-2 21:54:42 | 显示全部楼层

正解


。。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 18:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表