Introduction to RTOS Part 7 - Semaphore | Digi-Key Electronics

Introduction to RTOS Part 7 - Semaphore | Digi-Key Electronics

¿Cómo funcionan los semáforos en la programación concurrente?

Introducción a los semáforos y mutexes

  • En la lección anterior se comparó un mutex con una llave en una cafetería, que se utiliza para desbloquear y bloquear un baño compartido. Un semáforo también protege recursos compartidos, pero puede contar más de uno.
  • La analogía del baño no es suficiente, ya que aunque tengas una llave, necesitarías otro mecanismo para saber si el baño está ocupado. Los mutexes únicos son necesarios para proteger baños individuales.

Funcionamiento básico de los semáforos

  • Un semáforo permite que múltiples hilos accedan a una sección crítica, lo cual es útil como mecanismo de señalización más que permitir acceso simultáneo.
  • Se establece un valor inicial y máximo para el semáforo; por ejemplo, si se quiere permitir tres tareas al mismo tiempo en una sección crítica.
  • Cuando una tarea quiere acceder a un recurso compartido, verifica el valor del semáforo. Si es mayor que cero, decrementa su valor y entra en la sección crítica.

Ejemplo práctico de uso de semáforos

  • Tres tareas pueden trabajar simultáneamente en la sección crítica mientras el valor del semáforo sea positivo. Si llega una cuarta tarea, se bloquea hasta que alguna tarea termine.
  • Al finalizar su trabajo, cada tarea debe devolver el semáforo incrementando su valor nuevamente para permitir el acceso a otras tareas.

Limitaciones y mejores prácticas

  • Aunque esta teoría sobre los semáforos es válida, rara vez se utilizan así debido a la necesidad de proteger recursos individuales dentro de las secciones críticas.
  • Los semáforos son más efectivos como mecanismos de sincronización entre hilos en patrones como productor-consumidor.

Diseño productor-consumidor

  • En este diseño, varias tareas añaden datos a un recurso compartido (como un buffer), mientras otras eliminan datos.
  • El tamaño del recurso compartido puede limitarse ajustando el valor máximo del semáforo; si está lleno, no se pueden añadir más elementos.

Comparación entre mutexes y semáforos

  • A diferencia de los mutexes que implican propiedad (una tarea posee el mutex mientras trabaja), los semáforos no implican tal propiedad; deben ser utilizados para señalar disponibilidad.
  • Las implementaciones de objetos kernel como mutexes suelen incluir herencia de prioridad; esto no ocurre con los semáforos.

Herencia de Prioridad en Semáforos

Concepto de Herencia de Prioridad

  • La herencia de prioridad en semáforos implica elevar automáticamente la prioridad de las tareas que sostienen bloqueos mutex para evitar que una tarea de mayor prioridad se bloquee durante mucho tiempo.
  • Esta técnica ayuda a mitigar el problema del "inversión de prioridades", un tema que se abordará más adelante.

Diferencias entre Semáforos y Mutexes

  • Un semáforo binario solo cuenta hasta uno, lo cual puede parecerse a un mutex, pero no son lo mismo; los semáforos son útiles en rutinas de servicio de interrupción.
  • En estas rutinas, no es recomendable usar un mutex ya que podría bloquearse esperando recursos.

Terminología y Uso

  • Los semáforos POSIX utilizan términos como "post" y "wait"; es importante consultar la documentación del sistema operativo para entender su vocabulario específico.

Implementación Práctica con Semáforos Binarios

Caso Práctico: Uso de Semáforo Binario

  • Se propone crear un semáforo binario inicializado en cero, permitiendo que la función setup espere hasta que los parámetros sean leídos correctamente.
  • Al ejecutar este código, se observa cómo el número ingresado se pasa a la tarea blink utilizando el semáforo como señalización.

Expansión a Semáforo Contador

  • Se introduce un demo con un semáforo contador creado con cinco tareas; cada tarea copia contenido y lo imprime antes de eliminarse.
  • Se utiliza un bucle for para generar nombres únicos para cada tarea y pasarles punteros al mensaje estructurado.

Desafío: Protección del Puerto Serial

Consideraciones sobre Recursos Compartidos

  • El puerto serial no está protegido como recurso compartido, lo cual puede causar superposiciones en la salida.
  • Se sugiere tratar las declaraciones serial.print como una sección crítica usando mutexes para mejorar la protección.

Proyecto Final: Buffer Circular Compartido

Estructura del Proyecto

  • El proyecto involucra cinco tareas productoras que añaden valores a un buffer circular y dos consumidoras que leen desde él.
  • Cada productor escribe su número tres veces en el buffer; el objetivo es proteger este buffer usando mutexes y semáforos.

Requerimientos Adicionales

Video description

A semaphore is a signaling mechanism used to synchronise two or more threads. Similar to a mutex, it can be used to protect shared resources. In this video, we show you how to use semaphores with FreeRTOS on an ESP32 to pass data between tasks. The starting code for the challenge can be found here: https://github.com/ShawnHymel/introduction-to-rtos/blob/main/07-semaphore/esp32-freertos-07-challenge-counting-semaphore/esp32-freertos-07-challenge-counting-semaphore.ino The solution to the challenge in the video can be found here: https://www.digikey.com/en/maker/projects/introduction-to-rtos-solution-to-part-7-freertos-semaphore-example/51aa8660524c4daba38cba7c2f5baba7 Code for this video series (including demonstrations, challenges, and solutions) can be found here: https://github.com/ShawnHymel/introduction-to-rtos A semaphore is similar to a mutex in that it is a locking mechanism used to tell tasks to wait if some resource is not available for use. However, semaphores are more than a simple lock: they can count to more than 1 and can therefore allow multiple threads to enter a critical section of code. In practice, however, we often do not want to let multiple threads manipulate shared data, and we would still need to protect that data (or shared resource) with something like a mutex. So, we use semaphores as a signaling mechanism to tell other threads when it is safe to access a resource or read new data. A buffer or linked list can be written to by a number of “producer” threads. Each time one of these producer threads adds data to this resource, it increments a semaphore, which is just a counting variable that can be accessed atomically. When a “consumer” thread wishes to read data from the resource, it decrements the semaphore count. If the semaphore is 0, that means no new data is available, so consumer threads must wait (e.g. enter the blocked state). Semaphores work similarly to mutex, but are generally used in different circumstances. We provide examples of these use cases in the video as well as issue a challenge to use semaphores on your own. Product Links: https://www.digikey.com/en/products/detail/adafruit-industries-llc/3405/7244967 Related Videos: Introduction to RTOS Part 1 - What is a Real-Time Operating System (RTOS)? - https://youtu.be/F321087yYy4​ Introduction to RTOS Part 2 - Getting Started with FreeRTOS - https://youtu.be/JIr7Xm_riRs​ Introduction to RTOS Part 3 - Task Scheduling - https://youtu.be/95yUbClyf3E​ Introduction to RTOS Part 4 - Memory Management - https://youtu.be/Qske3yZRW5I​ Introduction to RTOS Part 5 - Queue - https://youtu.be/pHJ3lxOoWeI​ Introduction to RTOS Part 6 - Mutex - https://youtu.be/I55auRpbiTs​ Introduction to RTOS Part 7 - https://youtu.be/5JcMtbA9QEE​ Introduction to RTOS Part 8 - https://youtu.be/b1f1Iex0Tso Introduction to RTOS Part 9 - https://youtu.be/qsflCf6ahXU Introduction to RTOS Part 10 - https://youtu.be/hRsWi4HIENc Introduction to RTOS Part 11 - https://youtu.be/C2xKhxROmhA Introduction to RTOS Part 12 - https://youtu.be/LPSHUcH5aQc Related Project Links: https://www.digikey.com/en/maker/projects/introduction-to-rtos-solution-to-part-7-freertos-semaphore-example/51aa8660524c4daba38cba7c2f5baba7 Related Articles: https://www.digikey.com/en/maker/videos/shawn-hymel/getting-started-with-stm32-and-nucleo-part-3-how-to-run-multiple-threads-with-cmsis-rtos-interface Learn more: Maker.io - https://www.digikey.com/en/maker Digi-Key’s Blog – TheCircuit https://www.digikey.com/en/blog Connect with Digi-Key on Facebook https://www.facebook.com/digikey.electronics/ And follow us on Twitter https://twitter.com/digikey