当信号量在 RTOS 中被释放或发出信号时会发生什么?
What happens when Semaphore is released or signaled in RTOS?
假设有 6 个任务,6 个中有 4 个(任务)正在等待信号量。当发出信号量时,RTOS
做出什么决定
- which tasks to pick from the waiting(for semaphore) list
- if one task is picked from the waiting list what will happen to remaining task i.e when will they run.
- when already a higher priority task is running.
所有 RTOS
的解决方案是否相同
如果这是一个 priority-based,抢占式多任务系统,那么 RTOS 调度程序将 运行 优先级最高的任务,即 ready-to-run。当信号量发出信号时,RTOS 调度程序 re-evaluates 最高优先级 ready-to-run 任务是什么,如果它与之前的 运行ning 任务不同,它将执行到该任务的上下文切换。
当有多个任务在等待同一个信号量并且该信号量发出信号时:
- 等待信号量的任务中优先级最高的任务将被执行ready-to-run。
- 剩下的任务会继续等待信号量。
- 如果之前 运行ning 任务的优先级高于 ready-to-run 之前的任务,则之前 运行ning 任务继续 运行。即使创建了等待任务 ready-to-run,它也不会 运行 直到它成为最高优先级任务 ready-to-run。
以上内容适用于所有priority-based抢占式多任务RTOS,不一定是所有RTOS。如果 RTOS 不支持优先任务,那么它可能会将信号量授予等待信号量时间最长的任务。它也可能使用 round-robin 调度程序,这样每个任务 运行 在预定的时间段内执行,而不是允许任务异步抢占对方。
Follow-up:
如果您使用信号量作为事件信号,并且有多个任务使用该事件,那么您将不得不仔细考虑设计。我不相信这可以用一个二进制信号量来完成。因为如果最高优先级的消费者任务获得信号量,做它的业务,然后在信号量再次发出信号之前再次等待信号量,那么最高优先级的消费者在每次发出信号时总是会获得信号量。较低优先级的消费者任务永远不会 运行 因为它们永远不会被授予信号量。
一种可能的解决方案是使用计数信号量。当事件发生时,信号量计数应设置为等于消耗任务的数量。然后每个消费任务获得信号量并将计数减一。在信号量计数减少到零之前,消费任务不应再次等待信号量。这将防止最高优先级的消费者在每个事件中多次获取信号量,因此它将允许每个消费者任务 运行 恰好一次以响应事件。
您可能想探索 publish-subscribe 设计模式,看看是否有更好的方法来满足您的情况。
假设有 6 个任务,6 个中有 4 个(任务)正在等待信号量。当发出信号量时,RTOS
- which tasks to pick from the waiting(for semaphore) list
- if one task is picked from the waiting list what will happen to remaining task i.e when will they run.
- when already a higher priority task is running.
所有 RTOS
的解决方案是否相同如果这是一个 priority-based,抢占式多任务系统,那么 RTOS 调度程序将 运行 优先级最高的任务,即 ready-to-run。当信号量发出信号时,RTOS 调度程序 re-evaluates 最高优先级 ready-to-run 任务是什么,如果它与之前的 运行ning 任务不同,它将执行到该任务的上下文切换。
当有多个任务在等待同一个信号量并且该信号量发出信号时:
- 等待信号量的任务中优先级最高的任务将被执行ready-to-run。
- 剩下的任务会继续等待信号量。
- 如果之前 运行ning 任务的优先级高于 ready-to-run 之前的任务,则之前 运行ning 任务继续 运行。即使创建了等待任务 ready-to-run,它也不会 运行 直到它成为最高优先级任务 ready-to-run。
以上内容适用于所有priority-based抢占式多任务RTOS,不一定是所有RTOS。如果 RTOS 不支持优先任务,那么它可能会将信号量授予等待信号量时间最长的任务。它也可能使用 round-robin 调度程序,这样每个任务 运行 在预定的时间段内执行,而不是允许任务异步抢占对方。
Follow-up: 如果您使用信号量作为事件信号,并且有多个任务使用该事件,那么您将不得不仔细考虑设计。我不相信这可以用一个二进制信号量来完成。因为如果最高优先级的消费者任务获得信号量,做它的业务,然后在信号量再次发出信号之前再次等待信号量,那么最高优先级的消费者在每次发出信号时总是会获得信号量。较低优先级的消费者任务永远不会 运行 因为它们永远不会被授予信号量。
一种可能的解决方案是使用计数信号量。当事件发生时,信号量计数应设置为等于消耗任务的数量。然后每个消费任务获得信号量并将计数减一。在信号量计数减少到零之前,消费任务不应再次等待信号量。这将防止最高优先级的消费者在每个事件中多次获取信号量,因此它将允许每个消费者任务 运行 恰好一次以响应事件。
您可能想探索 publish-subscribe 设计模式,看看是否有更好的方法来满足您的情况。