在这种特定情况下 RTOS 中的互斥锁

Mutex in RTOSes in this specific situation

考虑以下代码:

/*----------------------------------------------------------------------------
 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为每个任务分配了一个特定的时间,在这个时间结束后,它会切换到另一个任务。
然后在这个特定的时间内,在任务的无限循环中,可能会重复多次循环,直到任务的特定时间完成。
假设任务在不到其一半时间的时间内完成,那么它有时间再次完全 运行 此任务。 最后一行释放mutex后,会第二次实现mutex早于task2,对吗?
假设当 MCU 运行 Thread1_Functions 第二次发生定时器滴答时,那么 task2 不能 运行 因为 task1 拥有互斥锁,RTOS 运行 任务 1 再次发生,如果定时器滴答每次都发生在Thread1_Functions,然后task2没有机会运行ning,我说的对吗?

首先,让我澄清一下您描述的调度方法。你说,"RTOS assign a specific time to each task and after this time is over, it switches to the other task."这种调度方式,俗称"time slicing"。并且所有的RTOS也不一定一直使用这个方法。时间分片可用于具有相同优先级的任务(或者如果 RTOS 不支持任务优先级)。但是,如果任务有不同的优先级,那么调度程序将不会使用时间片,而是根据任务优先级进行调度。

但我们假设您的示例中的两个任务具有相同的优先级并且调度程序是时间分片的。

  1. Thread1 运行s 并获取互斥量。
  2. Thread1 的时间片到期,调度程序切换到 Thread2。
  3. 线程 2 尝试获取互斥锁但由于线程 1 已经拥有互斥锁而阻塞。
  4. 由于线程 2 被阻塞,调度程序切换回线程 1。
  5. Thread1 释放互斥。

释放互斥锁后,调度程序应切换到任何等待互斥锁的优先级更高的任务。但是由于 Thread2 具有相同的优先级,我们假设调度程序不切换并且 Thread1 在其时间片内继续 运行。

  1. 线程 1 再次尝试获取互斥量。

在您的场景中,线程 1 再次成功获取互斥锁,这可能导致线程 2 永远无法 运行。为了防止这种情况发生,互斥服务应该优先考虑对互斥的请求。来自更高优先级任务的互斥请求获得更高的优先级。来自同等优先级任务的互斥请求应该先到先得。换句话说,互斥服务应该将来自同等优先级任务的请求放入队列中。请记住,线程 2 已经有一个等待处理的互斥锁请求(上面的第 3 步)。因此,当线程 1 再次尝试获取互斥锁时(步骤 6),线程 1 的请求应该排在线程 2 的较早请求之后。当线程 1 的第二个互斥锁请求排在线程 2 的请求之后时,调度程序应该阻止线程 1 并切换到线程 2,将互斥锁交给线程 2。

Update:以上只是关于未指定的 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();  
    }
}