
- Una red ordinaria de Petri es un grafo dirigido bipartito cuyos nodos se compone por el conjunto P (places) y el conjunto T (transitions), por lo tanto cada arista une un nodo de un conjunto con un nodo del otro conjunto. Son útiles para visualizar y evaluar el funcionamiento de sistemas, para esta materia nos interesa poder visualizar fácilmente la presencia de deadlocks. También existen tokens que se generan o destruyen en los nodos de P a partir de las transiciones. En las redes generales de Petri, las aristas tienen pesos y para que los tokens de un nodo se consuman, deben ser igual a la cantidad (peso) que requiere dicha arista.
- Las funciones de entrada I(y) y de salida O(t) corresponden a todos los lugares que cuentan con una arista incidente en t o una arista incidente desde t respectivamente (siendo t una transición perteneciente a T).
- TODO
- TODO

- Las propiedades de tipo “Safety” son aquellas que deben cumplirse en todo momento de la ejecución de nuestro programa concurrente, ellas son la ausencia de deadlock (si dos procesos cuentan con un recurso que el otro necesita, ninguno podrá avanzar productivamente hasta que el otro suelte dicho recurso) y el cumplimiento de la exclusión mutua (se evitan las condiciones de carrera ejecutando el código de la sección crítica sin que dos procesos intercalen las operaciones de la misma, es decir, de forma atómica). Por el lado de las de tipo “Liveness”, estas son la ausencia de starvation (si un proceso necesita el acceso a un recurso, eventualmente lo conseguirá) y fairness (el scheduler busca asignar el procesamiento de la forma más equitativa posible a los procesos dentro de nuestro programa concurrente) .
- Un semáforo es una herramienta de sincronizar procesos la cual cuenta con un contador K (cuyo valor inicial se asigna con la instanciación del mismo), este contador le da vida a la disponibilidad de un recurso, por otro lado cuenta con un conjunto donde se encontrarán todos los procesos que estén esperando a la liberación de recursos (o que K sea incrementado). Cuando un proceso hace wait sobre el semáforo, se bloquea hasta que el valor de K se incremente en caso de que sea cero en tal momento y en caso contrario continúa la ejecución (restando 1 a K), al finalizar el procesamiento con tal recurso finalmente se debe hacer signal de forma que K vuelva a incrementarse en 1 y se despierte un proceso al azar dentro del conjunto de procesos que se encuentren bloqueados esperando.
- Un caso general es el del problema del productor-consumidor con buffer acotado, aquí debemos hacer uso de dos semáforos, uno para saber cuántos lugares disponibles hay en el búfer (los productores pueden dejar lo que sea que produzcan en el búfer una vez sean desbloqueados porque hay espacio en el mismo) y otro para saber cuántos “productos” hay en el búfer (los consumidores pueden tomar un “producto” del mismo cuando sean desbloqueados porque hay productos en el mismo).
Un productor hace wait sobre el semáforo de lugares_disponibles hasta que es desbloqueado por el signal realizado por algún consumidor.
Un consumidor hace wait sobre el semáforo productos_disponibles hasta que es desbloqueado por el signal realizado por algún productor.
Además del sincronismo que permite el semáforo, está el búfer y por lo tanto los procesos deben excluirse mutuamente para acceder al mismo y soltar o dejar productos.

- La motivación es que cada actor modifica su estado y memoria local en función de los mensajes recibidos (de forma asíncrona), de esta forma no es posible que existan condiciones de carrera ni un tratamiento especial sobre secciones críticas.
- Los actores poseen una dirección a la cual las demás entidades le envían mensajes de forma tal que estos mensajes se procesan en el órden que llegan a la casilla del actor, en cada procesamiento el actor deberá tener definido un “handler” en el cual se puede o no modificar el estado interno y la memoria del actor además de disparar nuevos envíos de mensajes hacia otras entidades. Los actores poseen un contexto al cual pueden pedirle su dirección y también al cual indicarle si quieren parar su ejecución.
- Un arbiter tiene la responsabilidad de proveer el ambiente asíncrono de ejecución para los actores, funciones y futures. Son capaces de crear un nuevo hilo del sistema operativo, ejecutar un bucle de eventos, generar tareas de forma asíncrona en ese bucle de eventos y actuar como ayudantes para tareas asíncronas.
Con cada Arbiter que se crea, también se crea un nuevo contexto de ejecución para los Actores. El nuevo hilo está disponible para añadir nuevos Actores, pero estos no pueden moverse libremente entre Árbitros. Sin embargo, los Actores en diferentes Árbitros pueden comunicarse entre sí ya que el método de transmisión de mensajes es independiente de si los Actores se ejecutan en el mismo Árbitro o en diferentes (siempre envían mensajes a una dirección).

- En el algoritmo distribuído de exclusión mutua cuando un proceso necesita ejecutar el código de una sección crítica le envía a los demás procesos un mensaje que contiene el nombre de la sección crítica, el ID del proceso que solicita ingresar a la misma y un timestamp. Una vez que todos los demás procesos le responden OK es que el proceso que envió esos mensajes puede ejecutar dicho código. También puede ocurrir que un proceso ya se encuentre ejecutando el código correspondiente a la sección crítica que otro proceso quiere ejecutar, por lo tanto va a responderle OK una vez finalice la ejecución del mismo, si varios procesos solicitan ingresar a la misma sección crítica mientras que otro se encuentra ejecutándolo, entonces este responderá OK a aquel con un timestamp menor (dado que los mensajes pueden llegar desordenados).
- TODO
- Las dificultades se encuentran en la comunicación y sincronización de procesos que forman arte del sistema distribuído. Es por ello que se hace uso de timestamps para ordenar aquellos casos donde varios solicitan ejecutar la misma sección crítica y además prevenir falsos deadlocks.
- El conocimiento se basa en toda la información disponible de una entidad que forma parte del ambiente distribuído, entre ellos existen:
- Conocimiento local → Contenido de la memoria local de la entidad y la información que deriva de ello.
- Información métrica → Cantidad de nodos y aristas del grafo que compone al sistema distribuído (nodos → entidades, aristas → entidades vinculadas).
- Propiedades topológicas del grafo.
- Mapas topológicos → Conocimiento de la vecindad dado una entidad en particular (N_in, N_out).

- Two-Phase Locking (2PL) → En la primera fase se toman todos los locks a utilizar y en la segunda se liberan (no se pueden volver a tomar locks ya pasada la primera fase).
Timestamp → Cada transacción al iniciarse recibe un timestamp único y global para garantizar el orden, cada archivo tiene un timestamp de lectura y otro de escritura (además de qué transacción hizo la última operación en cada caso). Se compara el timestamp de la transacción con los del archivo, si es mayor entonces la transacción está en orden y se hace la operación, en caso contrario se aborta la transacción. Una vez hecho el commit se actualizan los timestamps del archivo.
Control de concurrencia optimista → Se modifican los archivos de forma tal que al momento de hacer commit se verifica que otra transacción no haya modificado al mismo archivo (se espera que no hayan conflictos al commitear). En caso de haber conflictos se aborta la transacción.