在 Preemptive OS 中,在同一任务的函数之间使用 Mutex 或 Semaphore 是否合适?

In a Preemptive OS is it proper to use a Mutex or Semaphore between functions in the same task?

我正在使用 RTOS。主程序除了Idle Task之外只有运行两个任务。

仅在单独的任务之间使用信号量或互斥量是好的编码习惯吗?或者在同一任务的函数之间?

考虑一下您使用互斥量或信号量的目的。它的目的是什么?然后在单个任务的上下文中考虑是否有必要。

互斥锁通常用于保护资源不被异步使用资源的事物同时访问。这里,"asynchronously" 表示使用该资源的事物未同步,可能会尝试同时使用该资源。现在,一个任务可以同时从两个不同的函数访问资源吗?不能,因为一个任务一次只能执行一个函数。由于任务一次只执行一个函数,因此单个任务中的不同函数已经同步。所以我会说互斥锁在只被一个任务使用时不会提供任何好处。

除了互斥量,信号量还有其他应用,例如发出事件信号。我想可能有一些应用程序在其中使用仅由一个任务访问的信号量是有意义的。但是你还没有描述你的申请,所以我会留给你自己考虑。

我会说它们主要用于任务间通信/同步/控制对资源的访问,所以它们主要用于任务之间而不是在同一个任务中。

可能存在并非如此的情况,但我目前真的想不出任何情况。

我个人认为一个任务最好只有一个暂停点,无论是从队列中放入或接收东西,等待互斥锁或信号量等。有些情况下这不是总是如此,但它确实使调试更容易。

在单个线程中 访问的互斥锁没有任何作用 - 锁定尝试总是会成功,因为没有其他线程会锁定它。如果互斥锁是嵌套的——即在解锁前被锁定不止一次,除了增加互斥锁的内部计数器之外,它也没有任何效果。

使用互斥锁来保护代码中的资源可能存在争议,稍后维护中可能会在多个线程中访问该资源;但在此之前,互斥量除了消耗 CPU 个周期外没有任何影响。


信号量在这种情况下的行为更为复杂,但信号量的目的是在 个任务之间进行同步和发送信号,因此在单个线程中几乎没有什么用处不能用简单的计数器或标志以更便宜的方式实现。

在这种情况下,信号量不如互斥量好;严格来说,如果在给出信号量之前尝试使用它,信号量 阻塞;因此,如果代码试图在信号量为空时获取信号量,任务将阻塞(停止 运行)。如果信号量有超时,则行为将是一个相当复杂的条件延迟,如果没有超时,任务将停止并且永远不会恢复,如果超时为零,则什么也不会发生。

因此在单个线程中,根据信号量的状态和使用的超时,它将表现为 task-suspendtask-延迟无操作。使用信号量来实现其中任何一个可能是不必要的混淆,因为任何 RTOS 都会有 API 来直接实现任务挂起和延迟。