考虑以下代码:
/*----------------------------------------------------------------------------
First Thread
*---------------------------------------------------------------------------*/
void Thread1 (void const *argument)
{
for (;;)
{
osMutexWait(mutex, osWaitForever);
Thread1_Functions;
osMutexRelease(mutex);
}
}
/*----------------------------------------------------------------------------
Second Thread
*---------------------------------------------------------------------------*/
void Thread2 (void const *argument)
{
for(;;)
{
osMutexWait(mutex, osWaitForever);
Thread2_Functions;
osMutexRelease(mutex);
}
}
据我所知RTOS's scheduling
,RTOS为每个任务分配了一个特定的时间,在此时间结束后,它将切换到另一个任务。
然后在这个特定的时间里,在任务的无限循环内,可能循环重复几次直到任务的特定时间结束。
假设任务完成的时间少于其时间的一半,那么它就有时间再次完全运行此任务。在释放互斥锁后的最后一行,那么它将比task2之前第二次实现互斥锁,我是真的吗?
假设在Thread1_Functions
第二次运行MCU时发生计时器计时,则任务2无法运行,因为任务1拥有互斥锁,RTOS再次运行任务1;如果计时器计时每次在计时器1中发生Thread1_Functions
,那么task2没有机会运行,是吗?
首先,让我清理一下您描述的调度方法。您说:“ RTOS为每个任务分配一个特定的时间,在此时间结束后,它将切换到另一个任务。” 这种调度方法通常称为“时间分片”。并且所有RTOS不一定总是使用此方法。时间分片可用于具有相同优先级的任务(或者,如果RTOS不支持任务优先级)。但是,如果任务具有不同的优先级,则调度程序将不使用时间片,而是根据任务优先级进行调度。
但是,假设您的示例中的两个任务具有相同的优先级,并且调度程序是时间分片的。
释放互斥锁后,调度程序应切换到任何等待该互斥锁的更高优先级的任务。但是,由于Thread2具有相同的优先级,因此我们假设调度程序未切换,并且Thread1在其时间段内继续运行。
在您的方案中,Thread1成功地再次获得了互斥锁,这可能导致Thread2永远无法运行。为了防止这种情况发生,互斥锁服务应优先考虑对互斥锁的请求。来自优先级较高的任务的互斥体请求将获得更高的优先级。来自同等优先级任务的互斥体请求应先到先得。换句话说,互斥锁服务应将优先级相同的任务的请求放入队列。请记住,Thread2已经对互斥量有一个挂起的请求(上面的步骤3)。因此,当Thread1尝试再次获取互斥量时(第6步),Thread1的请求应排在Thread2之前的请求之后。当Thread1对互斥锁的第二个请求在Thread2的请求之后排队时,调度程序应阻塞Thread1并切换到Thread2,将互斥锁交给Thread2。
更新:上面只是一个未指定的RTOS如何处理这种情况的想法,以避免Thread2饿死。在下面的评论中,您没有提到特定的RTOS。我不知道Keil RTX是否能像我上面描述的那样工作。现在我想知道您的问题到底是什么。
您是在问这种情况下Keil RTX会做什么吗?我不知道。您必须查看osMutexRelease()的代码,以查看它是否切换到具有相同优先级的任务。还要查看osMutexWait(),以了解它如何确定优先级相同的任务的优先级。
或者您是在说Keil RTX允许Thread2在这种情况下饿死,您是否正在询问如何解决它。要解决这种情况,您可以在释放互斥锁后调用osThreadYeild()。像这样:
void Thread1 (void const *argument)
{
for (;;)
{
osMutexWait(mutex, osWaitForever);
Thread1_Functions;
osMutexRelease(mutex);
osThreadYeild();
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句