dso_2012 发表于 2012-5-14 14:12:21

RT-THREAD 的rt_thread_suspend 好像无法将任务挂起

最近在移植RT-THREAD 碰到了一个问题:我想在一个任务里面将另外一个任务挂起,在这个任务执行完毕才恢复挂起的任务,调用rt-threadAPI 函数 rt_thread_suspend 后 发现我想挂起的任务仍然在运行,这就很奇怪了,不知道大家是否也发现是这样子,这是RT-THREAD故意这样设计的吗?那有什么办法可以实现类似UCOS 下 OSTaskSuspend功能的?期待高手来帮我解答一下。

dso_2012 发表于 2012-5-14 14:39:54

刚才又单步跟踪了一下发现 rt_thread_suspend 中有这样一段 if (thread->stat != RT_THREAD_READY)
        {
                RT_DEBUG_LOG(RT_DEBUG_THREAD,\
                        ("thread suspend: thread disorder, %d\n", thread->stat));
               
                return -RT_ERROR;
        }
      好像是要等到我要挂起的任务不处于DELAY状态才能执行下面的操作,但是不解的是为什么要这么做,直接在就绪表里面把这个任务删除不久完了么,为什么要多一个这个判断呢,如果不判断会有什么问题呢?

kongan 发表于 2012-5-14 20:03:59

唉,我也遇到同样的问题。没解决,同问。

ffxz 发表于 2012-5-14 21:50:34

一个个是直接写代码不看文档提示呀

《RT-Thread编程指南》的6.7.9节:
注:如果挂起当前任务,需要在调用这个函数后,紧接着调用rt_schedule函数进行 *手动的线程上下文切换* 。

dso_2012 发表于 2012-5-15 09:41:43

可是我并不是挂起当前任务,我是在当前任务中挂起另一个任务,现在发现要加一个while来判断是否挂起成功,想知道的是,如果去掉 if (thread->stat != RT_THREAD_READY)这一段会有什么影响?

lovewwy 发表于 2012-5-15 10:36:56

dso_2012 发表于 2012-5-15 09:41 static/image/common/back.gif
可是我并不是挂起当前任务,我是在当前任务中挂起另一个任务,现在发现要加一个while来判断是否挂起成功, ...

一般你进入一个线程,另一个应该自动挂起了啊

dso_2012 发表于 2012-5-15 16:48:05

对,但是我现在想实现的是:我想要挂起的任务在 当前任务运行的整个过程中,不能再运行,直到我手动唤醒它。但是目前看来无法将其真正挂起,我用UCOS 系统是可以的,UCOS 直接操作了任务就绪表,将这个任务删除了。

tiancaigao7 发表于 2012-5-15 16:56:58

记得调用suspend之后线程会被挂起到下次任务调度的时刻

dso_2012 发表于 2012-5-15 19:09:37

那这个挂起就不是真正的挂起了,RTT 不能实现任务真正的挂起吗,除非人为地去手动唤醒它,就像UCOS那样。

tiancaigao7 发表于 2012-5-15 19:44:03

本帖最后由 tiancaigao7 于 2012-5-15 20:12 编辑

dso_2012 发表于 2012-5-15 19:09 static/image/common/back.gif
那这个挂起就不是真正的挂起了,RTT 不能实现任务真正的挂起吗,除非人为地去手动唤醒它,就像UCOS那样。 ...

我又重新看了一下源代码,发现suspend方法确实是会将当前线程挂起,指导resume函数将线程重新加入到线程切换队列中。因此我感觉你之前的现象可能是判断有错误。

ffxz 发表于 2012-5-15 23:37:47

dso_2012 发表于 2012-5-15 09:41 static/image/common/back.gif
可是我并不是挂起当前任务,我是在当前任务中挂起另一个任务,现在发现要加一个while来判断是否挂起成功, ...

请给出测试代码出来。

senjet 发表于 2012-5-26 21:50:07

类似的现象我也遇到,比如我想实现某个线程运行时将另外某个线程强制挂起,直到我手动恢复再接着运行,开始我也想当然的用suspend方法实现,可是现实情况是suspend方法挂起的线程如果处于非READY状态,是没法挂起的,只好用信号量等间接的实现,比较麻烦,不知是不是我对suspend理解错误了?

sunnydragon 发表于 2013-1-24 12:01:47

本帖最后由 sunnydragon 于 2013-1-24 13:20 编辑

楼主的意思应该是在自己的线程中去挂起并且是一直挂起其他线程,直到手动允许其恢复。这点在ucos中很好解决,使用suspend及resume即可。。但是在rtt中就得使用信号量,因为线程中大部分进入到挂起状态都是在执行rt_thread_delay()的时候,等delay时间到了,线程一样会进入到就绪队列中去。而使用信号量可以使被控制的线程自己主动被挂起,直到获得信号量,被控线程状态才转换为就绪状态。。这样做就可以解决楼主的问题。。这也是rtt与ucos中的一些细小差别~
页: [1]
查看完整版本: RT-THREAD 的rt_thread_suspend 好像无法将任务挂起