<aside>
✏️
Este enunciado lo mandó un compañero por el grupo de wpp, se observa que algunos ejercicios se repiten de exámenes anteriores.
</aside>
Ejercicio 1
Explicar y comparar busy wait, deadlock, race condition y starvation.
- Un busy wait se da cuando un proceso intenta de forma repetida acceder a un recurso compartido, esto provoca un uso ineficiente del procesador dado que podríamos estar usando al mismo para avanzar productivamente en otro proceso y hacer uso de herramientas de sincronización para acceder al recurso cuando sea posible.
- Un deadlock se produce cuando un conjunto de procesos no puede avanzar productivamente en su ejecución debido a que requieren tomar un recurso compartido que actualmente tiene otro proceso (y ese otro proceso también requiere tomar un recurso ya adquirido), por lo tanto se genera una dependencia circular que no es interrumpida y por ende ambos procesos quedan en ese estado.
- Las condiciones de carrera se dan cuando dos procesos ejecutan código de una sección crítica al mismo tiempo (el scheduler intercala las operaciones de la misma para ambos procesos), es por ello que se deben excluir mutuamente a los procesos en las secciones críticas y las mismas deben ser lo más pequeñas posibles, de esta forma el resultado sería determinístico en lugar de no determinístico (situaciones complejas de reproducir debido a los distintos escenarios que pueden resultar debido a las decisiones del scheduler).
- Starvation se da cuando un proceso no accede a un recurso el cual requiere para avanzar de forma productiva (ya sea porque otros procesos son elejidos por el scheduler para ello o por otras razones).
Ejercicio 2
Motivacion del modelo de actores, definir las caracteristicas de los actores y el ciclo de vida en el framework que usamos (actix).
- El modelo de actores busca que distintas entidades se ejecuten de forma asíncrona de forma tal que envién y reciban mensajes, instancien nuevos actores, establezcan relojes locales y modifiquen su propio estado y memoria local.
En el ciclo de vida de un actor el mismo es iniciado, ejecutando y se detiene. Durante su ejecución realizará las actividades mencionadas en el párrafo anterior, mediante los mensajes que reciba y en función de los handlers definidos sobre los tipos de mensajes que se encolen a su casilla de correo, el mismo procesará los mismos de forma secuencial de forma tal que no será necesaria la exclusión mutua ni contemplar posibles race conditions dado que el actor procesa los mensajes uno a uno y su estado y memoria no se comparte. Un actor puede detener su ejecución si lo pide explícitamente a su contexto mediante stop() o cuando el arbiter detecta que no existen más referencias a la dirección del mismo desde otros actores, también puede modificar la capacidad de su mailbox (el arbiter ejecuta el código asíncrono del actor y por ende al llegar los distintos tipos de mensaje ejecuta los “handlers” definidos en consecuencia).
Ejercicio 3
Explicar el sistema de deadlocks distribuido, graficar un ejemplo (y una cosa mas)
- En el algoritmo de detección de deadlocks distribuído contamos con un conjunto de procesos, cuando uno de ellos requiere un recurso que posee otro proceso construye un mensaje que contene el ID del proceso que se bloquea esperando el recurso, ID del proceso que envía el mensaje y el ID del proceso que recibe un mensaje. Cuando un proceso recibe este tipo de mensaje, en caso de requerir un recurso que tiene otro proceso modifica el mensaje recibido de forma que en el ID del proceso que envía el mensaje escribe su propio ID y en el ID del proceso que recibe el mensaje al del proceso que posee el recurso que este necesita. Por lo tanto si un mensaje llega al mismo proceso (el ID del proceso bloqueado es el mismo que el proceso que recibe el mensaje) entonces encontramos una dependencia circular y por ende un deadlock.

En este ejemplo el proceso 1 necesita el recurso B, por lo tanto envía el siguiente mensaje:
{id_bloqueado: 1, id_envia: 1, id_recibe: 2}
Pero el proceso 2 necesita el recurso C, por lo tanto envía el siguiente mensaje:
{id_bloqueado: 1, id_envia: 2, id_recibe: 3}
Al mismo tiempo el proceso 3 necesita el recurso A que posee el proceso 1 y envía el siguiente mensaje:
{id_bloqueado: 1, id_envia: 3, id_recibe: 1}
Al llegar el mensaje al proceso 1 se detecta el ciclo en el grafo de uso de recursos y por ende encontramos el deadlock.