tema 6: concurrencia - ulpgc
TRANSCRIPT
Sistemas OperativosTema 6. Concurrencia
1
© 1998-2008 José Miguel Santos – Alexis Quesada – Francisco Santana
Contenidos
� Sistemas concurrentes
� El problema de la sección crítica
� Semáforos
� Monitores
2
Bibliografía
� Fundamentos de Sistemas Operativos� S. Candela, C.R. García, A. Quesada, F.J. Santana, J.M. Santos.
Thomson, 2007
� Capítulo 3
� Programación Concurrente� J.T. Palma, M.C. Garrido, F. Sánchez, A. Quesada
� Capítulos 1, 2, 3, 4, 5 y 6
� Principles of Concurrent and Distributed Programming� M. Ben-Ari. Prentice Hall, 1990
� Concurrent Programming� A. Burns, G. Davies. Addison-Wesley, 1993
3
Contenidos
� Sistemas concurrentes
� El problema de la sección crítica
� Semáforos
� Monitores
4
Modelo del sistema
� Conjunto de procesos cooperativos� Red de cajeros automáticos
� Sistema de reserva de billetes
� Servidor de impresión
� ...
5
¿Qué es concurrencia?
� Definición de diccionario: coincidir en el espacio o en el tiempo dos o más personas o cosas.
� En Informática, se habla de concurrencia cuando hay unaexistencia simultánea de varios procesos en ejecución.
� Ojo, concurrencia existencia simultánea no implica ejecución simultánea.
6
Paralelismo y concurrencia
� El paralelismo es un caso particular de la concurrencia.
� Se habla de paralelismo cuando ocurre la ejecución simultánea de instrucciones.
7
Procesos cooperativos
� Necesidades de sincronización y comunicación
� Los procesos concurrentes tendrán necesidad de comunicarse información
� Además, será necesario en ocasiones detener a un proceso hasta que se produzca un determinado evento o se den ciertas condiciones � sincronización
8
Técnicas de sincronización
� Basadas en memoria compartida� Inhibición de Interrupciones
� Espera activa� Semáforos� Regiones críticas� Monitores
� Basadas en el paso de mensajes� Canales� Buzones
9
Ejemplo 1: modificación concurrente de una variable
������������� ����
����������
�������������������� ��������������
����������� ����������������������� ������������������ ���� ������������������������������� �
�������������� ������� ������ ��� �� �����������������
10
Ejemplo 2: bucles infinitos concurrentes����������������� ���
���� !�"���������
����������#���� �������� ���$ ��%���" � �&���� ��������'�%� ������ !�"������� !�"���� ��� �������#���� �
����������(��"���������� ���� �����" ��� �'�" $ ������)#��'��&���' ��� !���)����������������� !�"��� ������ !�"��� ��� ����
����������� !�"���� ������� ��#���� �� ��(��"����� ��������������� �
11
Ejemplo 3: búfer limitado
��������"�!���"� �*������������������ �����+'������� !�",-������!���������.�//�"����" �������������" ����" ���������� !�"����� !�"�����!�������
-������ �������*�"�000��1��������������000�.�//�"�� "" 1��00-�����/�������������" 2 ������!�-������� !�"������*�"�" �*���00-������
������������� �����+'������� !�"��������!��������������.�//�"� ������� ��� ������������ !�"����� !�"������������"����������!�������
Productor Consumidor
12
Problema al modificar datos compartidos
� Ambas rutinas son correctas si se ejecutan por separado pero podrían NO funcionar si se ejecutan de manera concurrente
� Supongamos que contador contiene en un momento dado el valor 5 y que las instrucciones “contador=contador+1” y “contador=contador-1” se ejecutan de forma concurrente (¡contador podría ser 4, 5 o 6!)
contador = contador + 1 contador=contador-1 registro
1 := contador; registro
2 := contador;
registro1 := registro
1 +1; registro
2 := registro
2 -1;
contador : registro1; contador := registro
2;
T0: productor registro1 := contador (registro
1= 5)
T1: productor registro1 := registro
1+1 (registro
1 = 6)
T2: consumidor registro2 := contador (registro
2 = 5)
T3: consumidor registro2 := registro
2 -1 (registro
2 = 4)
T4: productor contador := registro1 (contador = 6)
T5: consumidor contador := registro2 (contador = 4)
13
Contenidos
� Sistemas concurrentes
� El problema de la sección crítica
� Semáforos
� Monitores
14
Sección crítica: modelo del sistema
� N procesos intentan acceder a un recurso compartido en un bucle infinito:
���
��3����4��-��#"5��� ��3-#������� ������� ����3����4��#"5��� ��3#��
������ ������� ����� ����
� Sección crítica: segmento de código donde se accede a datos compartidos con otros procesos
15
Sección crítica: modelo del sistema (2)
� Nunca puede haber más de un proceso en la sección crítica (exclusión mutua)
� Los pre y post protocolos serán algoritmos para garantizar que se cumple la exclusión mutua
16
Requisitos de la solución
� Exclusión mutua� Progreso: si ningún proceso está en sección
crítica y hay procesos que desean entrar en su s.c., sólo estos últimos participarán en la decisión y ésta se tomará en un tiempo finito.
� Espera limitada: hay un límite para el número de veces que otros procesos pueden adelantarse a un proceso que quiere entrar en s.c.
17
Importante
� Suponemos que cada proceso se ejecuta a una velocidad distinta de cero
� No podemos hacer suposiciones acerca de las velocidades relativas de los procesos
18
Solución trivial: cortar la multiprogramación
� Si suspendemos la multiprogramación, desaparece el problema de acceso a los datos compartidos…
� …pero perdemos todas las ventajas de la multiprogramación
� Hay que buscar una solución menos radical
19
Solución del hardware:inhibir las interrupciones
� Antes de que un proceso entre en su sección crítica, se inhiben las interrupciones
� Así es imposible que el proceso sea expulsado de la CPU mientras está accediendo al dato compartido
� Al salir de la SC, se rehabilitan las interrupciones
20
Inhibir las interrupciones: problemas
� Mientras un proceso está en SC, se suspende toda la concurrencia en el sistema� no se le da oportunidad a otros procesos que no están accediendo al recurso compartido
� Esta técnica no se puede implementar en un multiprocesador
21
Soluciones con espera activa
� La sincronización se basa en que un proceso espera mediante la comprobación continua de una variable, manteniendo ocupada la CPU.
� Soluciones Software
� Soluciones Hardware
22
Intento ingenuo:usar un indicador de disponibilidad
23
���6 "� .���*��. ������!�� ���� �����4���"5��� ���7���."���."���.���� �����"���
����4!�*��&��������� �� ! ��"����������!�����"�����#���$!����������������+'�����."�������!����������."����/ ���!�����"���#���$!����."�����"�����!������
������3-# �����������������+'�����"�� ��
��!��������3# �����"�������!������
������3-#������������������+'�����"��������!��������3#������"��� ���!������
Primer intento serio:variable turno
��"���������6��" �*���00 �����
24
(solución para dos procesos)
proceso 1 proceso 2
Discusión del primer intento
� ¿Exclusión mutua?
� ¿Espera limitada?
� ¿Progreso?
25
������3-#�����������������+'�����."� �����!����������."���/ �����3#������."����"�����!������
������3-# ����������������+'�����."�������!����������."� �/ �����3# �����."� ��"�����!������
Segundo intento: avisadores
��."��2���."� ��.���� �����"���
26
proceso 1 proceso 2
Tercer intento
������3-#������."���/ ������������������+'�����."� �����!����������3#������."����"�����!������
������3-# �����."� �/ �������������������+'�����."�������!����������3# �����."� ��"�����!������
��."��2��."� ��.���� �����"���
27
proceso 1 proceso 2
������3-#������."���/ �������"���� �����������������+'�����."� ��"� � � ����"��������!��������3#������."����"�����!������
������3-# �����."� �/ �������"���������������������+'�����."����"� � � ����"�� �����!��������3# �����."� ��"�����!������
Algoritmo de Peterson - ¡¡FUNCIONA!!� � ��."��2���."� ��.���� �����"���� � ��"���������6��" �*���00 �����
28
�����%&�"������ �������'�(�)����"�����#���$*�+�����*���!�����"������"���������������������89:��������000�������������*���!�����"�����/ �����/�"�������00-�������������������������+'���������*���!�����"�����������!�������������������������+'�������"����������"�������������������������������"��������������� �!������������!����������!������)����"���#���$*�+�������"���������!������
Solución para N procesos: Algoritmo de la panadería (Lamport)
��*���!�����"��� "" 1��00-���/�.���� �������'�"�/ ��������� "" 1��00-���/�� ��" �������'�"����
29
Soluciones hardware
� Inhibir interrupciones (muy drástico)
� Instrucciones atómicas test-and-set o SWAP.
30
Instrucciones atómicas
� Inventadas en los años 60.� Permiten evaluar y asignar un valor a una
variable de forma atómica.� test-and-set(B): Pone B a true y devuelve el antiguo
valor de B. (Evaluar-y-Asignar(B))
� SWAP(A,B): Intercambia los valores de A y B. (Intercambiar(A,B))
� Si disponemos de estas instrucciones, se simplifica muchísimo el problema de la sección crítica.
31
Ejemplos de algoritmos
������3����4������"5��� ����������������+'����������,��� $�� )��* $-�+.�$ �������!��������3����4���"5��� ����� 6��/ �����!������
������3����4������"5��� ��� ����"����&&/-$��$� � ��$ 0����������)1$�* $-�2$�3+����������+'��� ��/ �������!��������3����4���"5��� ����� 6��/ �����!������
32
usando test-and-set
usando swap
Solución completa (test-and-set)
�����!�-��� 6��.���� ���������)���������" �!������"�������� 6���"������+'�������" �!����� �!��� 6������������� 6��;��� �!�3�����"" !�" �������!�����������" �!�����/ ���
��)���
����������+'������<��� �!��������" �!�����������������������!���������/�����'��������"" !�" �/ ���������������" �!�����/ ���������!��/���!������
� ���" �!��� "" 1��00-�����/�.���� �������'�"���/ ����� ��"" !�" ��.���� ����/ ���
33
Contenidos
� Introducción
� El problema de la sección crítica
� Semáforos
� Monitores
34
Semáforos
� Edsger Dijkstra, 1965
� Objetivo: herramienta universal para sincronizar procesos, que sirva como componente básico para construir algoritmos concurrentes
35
Concepto de semáforo
� Dijkstra lo definió como una variable entera S con dos operaciones atómicas:
� P(S): esperar a que S>0;
S:=S-1;
� V(S): S:=S+1;
� NOTA: el semáforo no puede adquirir valores negativos
36
Semáforos: otras notaciones
� P(s) = wait(s) = espera (s)
� V(s) = signal(s) = señal (s)
� (se utilizan varias notaciones para las operaciones de los semáforos, pero significan lo mismo)
37
Ejemplo: sección crítica resuelta con semáforos
� Usamos un único semáforo inicializado a uno.
.�*����3����4������"5��� �����������3����4���"5��� ����������!�
38
Semáforos: esperar por eventos y condiciones� Se asocia un semáforo, inicializado a cero, al evento
por el que queremos esperar. Cuando un proceso ha hecho que se cumpla una determinada condición, lo indica ejecutando un signal(c). Un proceso esperará a que la condición sea cierta mediante un wait(c).
��.�*����3�����*� ������ 3 ���!�
�4.�*����=����+ ������� = ���!�
39
Semáforos: ejercicios
� Ejercicios� a.-) Resolver el problema de la sección crítica con n
procesos
� b.-) Resolver diversos problemas de sincronización� b.1.-) Sean P1 y P2 dos procesos concurrentes. Modificar el
código de ambos procesos de forma que el conjunto de sentencias R2 del proceso 2 se ejecute después de que se
��.�*����3����3 ���!�
�4.�*����=����= ���!�
40
Semáforos: ejercicios
� b.2.-) Realizar un pequeño programa que se
ajuste al siguiente diagrama (o grafo) de
precedencia (suponiendo que disponemos de las
herramientas siguientes: sentencia concurrente
cobegin/coend )
A
B
C
D
41
Semáforos: ejercicios
� b.3.-) Realizar un pequeño programa que se
ajuste al siguiente diagrama (o grafo) de
precedencia (suponiendo que disponemos de las
herramientas siguientes: sentencia concurrente
cobegin/coend y semáforos)
A
B
C
D
42
Semáforos:implementación con espera activa
1$��*�+5���+'����,��!��� ! ��������
����$ *�+5�������
43
� También llamados spinlocks
Semáforos:implementación sin espera activa
� Suponemos que el SO proporciona unas operaciones para bloquear y desbloquear procesos
�1���3��7/�"����"���"!� 6 ��"�����*�"�� ������ ,�"��������!�"���"!�
����$ *�+5� 06 ��"���06 ��"�������/�06 ��",���'���������0���" �"��"������������ ����������"�����������!��/����
1$��*�+5���06 ��"���06 ��"�������/�06 ��",���'���������0���"� "��"����9��� �������������������"����9��� ��������!��/�
44
Semáforos: la implementación debe garantizar atomicidad
� Es crítico que las operaciones se ejecuten de forma atómica
� Entorno uniprocesador:� Inhibir interrupciones
� Entorno multiprocesador:� Instrucciones hardware especiales� Aplicar un algoritmo de sección crítica con
espera activa
45
Semáforos binarios
� Los semáforos vistos reciben el nombre de semáforo general o semáforo de conteo
� Un semáforo que sólo puede tomar los valores 0 y 1 recibe el nombre de semáforo binario
46
Ejercicio
� Implementación de un semáforo de conteo con semáforos binarios
47
Problemas clásicos de sincronización
� Problema del búfer limitado
� Problema de los lectores y escritores� 1er problema: prioridad para los lectores
� 2º problema: prioridad para los escritores
� Problema de los filósofos comensales
48
Búfer limitado
�������000����"�!���"��������������������000������" �6 �����������" ���"" !�" �����.�//�"����" �������������" ����" �������> ����"" !�" ������> �����������!�������
-������ �������*�"�000��1��������������000�.�//�"�� "" 1��00-�����/�������������" 2 ������!�-������������ /�"�����6 ������� /�"���-���"" !�" ���� /�"�������
����������" ��������������" ���"" !�" ����������.�//�"� ������� ��� ���������> ����"" !�" ������> ��6 ��������000���������"�����������������000��!�������
Productor Consumidor
49
Lectores y escritores
� Esquema útil para gestionar el acceso a una base de datos:� Puede haber varios lectores accediendo a la BD
de forma concurrente
� Sólo puede haber un escritor trabajando
� No puede haber lectores y escritores al mismo
tiempo
� … y si se puede, que no haya inanición
50
Lectores y escritores:dos variantes
� Primera variante: prioridad para los lectores� Si un escritor está esperando, se le pueden
adelantar otros lectores
� Ojo, riesgo de inanición para los escritores
� Segunda variante: prioridad para los escritores� Si hay escritores esperando por la BD, los
lectores que van llegando nuevos se deben esperar hasta que todos los escritores finalicen
� Ahora hay riesgo de inanición para los lectores
51
Lectores y escritores: 1ª variante
����������" ���"" !�" �����������"��������"��������/�������"����'�����������" ���"���" ������> ����"" !�" �����67�68���������" ���"" !�" �����������"��������"��������/�������"����'���������> ����"���" ������> ����"" !�" ����!�������
��"" !�" ���� /�"�������"���" ���� /�"�����������"���� ��" �����
����������" ���"���" �����)�7���7�68�������> ����"���" ����!�������
Lector Escritor
52
Lectores y escritores: 2ª variante
53
���" ���""�������+'������"�.���!���"�����������������������> ����""������������" ���""���������!��������������������������> ����""�����! ����� $��!
���" ���""�������������������?����> ����""�����
��""������3��7/�"��������"�.���!����.���� ����/ �������2������� ��" ������
���" ���""�����������������������+'������"�.���!���"������������������������> ����""������������" ���""���������!��������������������������"�.���!�����"�����> ����""�����!���������� $��!
���" ���""���������"�.���!����/ ����> ����""�����
LectorEscritor
Los filósofos
54
Los filósofos: modelo simple
����������" �� ����������������" �� ������������!�����999
��:7�
999
����> ��� ��������������> ��� ������������!�������999��)87�
999
��!�������
� ������� "" 1��00@���/��� /�"�������'�"����
55
Filósofos: ojo al interbloqueo
� La solución anterior puede entrar en un estado de bloqueo mutuo entre todos los filósofos � interbloqueo
� Posibles soluciones:� Algoritmo asimétrico filósofos pares/impares
� Impedir a más de cuatro filósofos entrar a pedir
los palillos
� Coger los dos palillos de forma atómica (o coges
los dos, o no coges ninguno)
56
Los semáforos ayudan, pero tienen limitaciones…
� Los semáforos son una herramienta de bajo nivel, que requiere un uso disciplinado y cuidadoso.
� Es muy fácil cometer errores de uso con semáforos.
� Veamos algunos ejemplos…
57
¿dónde está el fallo?
Sem = 0
P (sem)
… sección crítica …
V (sem)
58
¿dónde está el fallo?
3�����
6��!�"���� ����������������� ����A
������3�������%��4!�*��!������4���"5��� �����/����""�"���"���"������%��7��4!�*��!������4���"5��� ���B�����
C
59
Más problemas…
Proceso 1
P (impresora)
P ( disco ) … usar disco e impresora
V (disco)
V (impresora)
Proceso 2
P (disco)
P ( impresora ) … usar disco e impresora
V (impresora)
V (disco)
60
Dos procesos que acceden a recursos compartidos:¿qué ocurre al ejecutarlos al mismo tiempo?
Herramientas de alto nivel
� Objetivo: introducir en el lenguaje de programación herramientas de sincronización que sean más seguras que los semáforos
� Ejemplos:� Regiones críticas
� Monitores y variables condición
61
Regiones críticas condicionales
� Abstracción de un bloque de código que accede a recursos compartidos.
� Garantiza exclusión mutua.� El código sólo se ejecuta si la condición
asociada a la región crítica es cierta.� Ejemplo:
"�*����DE/�"�+'���-�������������A���<<������4!�*���������� ����������4������ ���<<�1�4����������� ���-���������������%�������"�������������!���.E/�"�%���-����������-���������?���C
62
Regiones críticas condicionales
� Se plantearon en 1972 (Brinch Hansen, Pascal Concurrente)
� Gran fuerza expresiva, el código queda mucho más legible y compacto
� Problema: implementación muy costosa, comparada con el código escrito a mano con semáforos
� Por ese motivo, nunca llegaron a prosperar como herramienta de uso común
63
Contenidos
� Introducción
� El problema de la sección crítica
� Semáforos
� Monitores
64
Monitor
� Propuesto por Hoare (1972)
� Tipo abstracto de datos� Estructura de datos privada
� Operaciones públicas
+� Exclusión mutua
� Sincronización (variables condición)
65
Monitor: ejemplo básico
66
��������#��� !�"�A��<<����" �������E.��� ����.����#��� !�"����A�6 ��"�����C����.����6��!����"����� ���A�6 ��"����C����.�������� ��� ����A�"���"��6 ��"��C
������6 ��"���<<�6 "� .�������"� ��"�6 ! C�
#��� !�"0���"����� ���B��#��� !�"0 ��� ����
Si varios procesos intentan manipular el monitor almismo tiempo, van entrando de uno en uno: no puedehaber más de un proceso trabajando con el monitor encada momento.
Monitor: estructura interna
67
Variables condición
� Una variable condición sirve para gestionar una cola de espera por el monitor
� Dos operaciones� x.wait
� bloquea al proceso y lo mete en la cola “x”
� x.signal
� desbloquea a un proceso de la cola “x”; si no
hay procesos en “x”, no hace nada
68
Variables condición: ejemplo
69
������"�#��� !�"�A������������� $�����.����#��� !�"����A�6 ��"�����C
����.����6��!�D��&�� F � G��B �* H��I���A�����/���6 ��"�,������A��� $91$������C��C
����.����6��!�(��"����� ���A�����6 ��"��������/���6 ��"�������A��� $9����$ ����C��C
������6 ��"�C�
Monitor con variables condición
código de inicialización
x
y
datos compartidos
colas asociadas a las variables condición x e y
cola de ingreso
...
operaciones
70
Qué ocurre tras un “signal”
� ¿ Qué ocurre cuando un proceso P realiza una operación signal sobre una variable condición x y existe un proceso suspendido Q asociado a dicha variable?
� Estilo Hoare � se reanuda Q inmediatamente
� Estilo Mesa � Q se desbloquea, pero espera a que
P abandone el monitor
� El estilo Mesa es el más utilizado en los lenguajes de programación actuales
71
Qué ocurre tras un “signal” (2)
� Si varios procesos están suspendidos por la condición x y algún proceso ejecuta x.signal, ¿ qué proceso se reanuda?� FIFO � desbloqueamos al más antiguo
� Por prioridades � conveniente en sistemas de
tiempo real
72
Ejemplo: un semáforo implementado con un monitor
73
��������3��7/�"��A������6 ��"���������������� �
����� ���3��7/�"�������6 ���A�6 ��"��6 ���C
����� ���6��!�����A����+'������6 ��"������A���� 01$������C����6 ��"�����C
����� ���6��!�B���A�����6 ��"���������� 0����$ �����CC�
Ejemplo: búfer limitado
74
��������DE/�"�A������������' 1F����2�' 1(������������������������������-��%�
��� ���6��!����"� "��(�������A����+'�����������-���A�' 1F����0+ ������C����%����"�!���"���������.E/�"�%����������������' 1(���0�*� ������C
����� ���(�������" �"���A����+'���������������A�' 1(���0+ ������C����(�������%����" �� �*��%����������������' 1F����0�*� ��������"���"������CC�
Cómo se implementa un monitor
75
�������8�8�����"�A���.����6��!����"���%��A�%�C���.����6��!����" ��%��A�%�CC�
� $���8�8�����"�A��)��;�����������.������.����6��!����"���%��A�����������9�*+�����%����"���!�����"��%�����������9<*+���C����.����6��!����" ��%��A�����������9�*+�����%����"���!�����" �%�����������9<*+���CC�
El compilador generaun código parecido a este:
El cerrojo garantiza que nopuede haber más de un procesodentro del monitor
Cómo se implementa un monitor:variables condición
76
��������8�8�����"�A�������������!
�91$��*+�
!
�9����$ *+�
!
C�
��������8�8�����"�A��3��7/�"����""�������
��3��7/�"����&�������������������������
������������""���0B����==�9 ������ ���������&����0�����==49��� �>����� $�� $��""���0�����==?9��$��������� �>�����������������==�����������$�� �������
���/�������������A�==���$@$ ����������$����������������������== �����$���������&����0B������==@ ����� �>�����C
Monitores:ejemplos más avanzados
77
Lectores y escritores (1)
78
������"�D �H ���A����.���������I �����" ���A�%�C����.����;�"��� �����" ���A�%�C����.���������I ��"���" ���A�%�C����.����;�"��� ��"���" ���A�%�CC�
6��!����"���A�==6�>������������$��� �������D �H ��0�����I �����" �����%����"�!��� �DH�%��D �H ��0;�"��� �����" ���C
6��!���"�.�"���A�==6�>������������$�������������D �H ��0�����I ��"���" �����%���"�.�"����� �DH�%��D �H ��0;�"��� ��"���" ���C
Lectores y escritores (2)
79
������"�D �H ���A��#��!���������"2���"�.�"������������2�������" �����.������"�.���!���/ ���
����.���������I �����" ���A����+'�������"�.���!���A������������" ��������������"0+ �����������������" �����C������������������"0�*� �����==���� �>��$���$���$$ �������C�
����.����;�"��� �����" ���A����������������/���������A���"�.�"0�*� �����C��C
Lectores y escritores (y 3)
80
����.���������I ��"���" ���A����+'������������JJ���"�.���!���A���"�.�"0+ ������C������"�.���!����"�����C�
����.����;�"��� ��"���" ���A������"�.���!���/ ��������/��������" �������A����"0�*� �����C��������A���"�.�"0�*� �����C��C
};
Filósofos (1): especificación del monitor
81
��������8� K��4�/��A
��==���$����������� ������$�����������-����#��!���������!�#���"L-M���������� !��A���� �!�2�' �."�����2�������!��C����� !���� !�L-M��A���'�"������ �!��C�
==����$�������A� ��$�*-�������������;���$�+
����.����#�*�� ������������/����/����A�%�C����.����3���� � ������������/����/����A�%�C
==����$��"�$�3� �$�������$
���"�6 �������"��. G�����!�#���"�������/����/����A�%�C�C�
Filósofos (2): ejemplo de uso
82
-����B�! H��K��4�/����������K����/����A�
�������A�������� N������������8� K��4�/�0#�*�� ���������K����/�����������9""�I�������8� K��4�/�03���� � ���������K����/�����CC
Filósofos (3): rutina auxiliar
83
==����$��"����-$�$�������� �������:��$B� "�����
���-$�����������$C�������������������/����/����A
��������6�����H�"��' ���/����/�����O�-���������6�����(I&���"! ���/����/����-��O�-���������/����� !�L6�����(I&���"! M�P�������!��QQ����������� !�L6�����H�"��' M�P�������!����A��������� !�L/����/�M��������!������������!�#���"L/����/�M0�*� ��������C��C
Filósofos (y 4): operaciones públicas del monitor
84
����.����������$ � ���������/����/����A������ !�L/����/�M��' �."��������������"��. G�����!�#���"�/����/��������/����� !�L/����/�M�P�������!����A����������!�#���"L/����/�M0+ ���������C��C
����.����)� �$��$ � ���������/����/����A������ !�L/����/�M����� �!����������6�����H�"��' ���/����/�����O�-���������6�����(I&���"! ���/����/����-��O�-���������"��. G�����!�#���"��6�����H�"��' ����������"��. G�����!�#���"��6�����(I&���"! ����C