programación concurrente dai - unsaac.. motivacion se ha preguntado alguna vez, de cómo se...
Post on 07-Feb-2015
6 Views
Preview:
TRANSCRIPT
Programación ConcurrenteProgramación Concurrente
DAI - UNSAAC.DAI - UNSAAC.
MOTIVACIONMOTIVACION
Se ha preguntado alguna Se ha preguntado alguna vez, de cómo se realizan vez, de cómo se realizan los siguientes sistemas?los siguientes sistemas?
Simulador de vuelosSimulador de vuelos
Sistemas de tiempo realSistemas de tiempo real
Modelamiento y Modelamiento y simulacionsimulacion
RoboticaRobotica
Juegos de videoJuegos de video
¿Que es la ¿Que es la Concurrencia?Concurrencia? Definición Real Academia Española.Definición Real Academia Española.
Acaecimiento o concurso de varios sucesos Acaecimiento o concurso de varios sucesos en un mismo tiempo.en un mismo tiempo.
Una forma de ver la concurrencia es Una forma de ver la concurrencia es como un conjunto de actividades que como un conjunto de actividades que se desarrollan en forma simultánea.se desarrollan en forma simultánea.
En informática cada una de esas En informática cada una de esas actividades se suele llamar actividades se suele llamar proceso.proceso.
¿Que es la ¿Que es la Concurrencia? (cont.)Concurrencia? (cont.) En informática se habla de En informática se habla de
concurrencia cuando hay una concurrencia cuando hay una existencia simultánea de varios existencia simultánea de varios procesos en ejecuciónprocesos en ejecución..
Ojo.... existencia simultánea no Ojo.... existencia simultánea no significa ejecución simultánea.significa ejecución simultánea.
1.1.Verter ingrediente uno y dos en un Verter ingrediente uno y dos en un recipiente y batir durante 10 minutos.recipiente y batir durante 10 minutos.
2.2.Dejar reposar 2 minutos.Dejar reposar 2 minutos.
3.3.Mezclar el ingrediente tres y cuatro en Mezclar el ingrediente tres y cuatro en otro recipiente y batir durante 5 minutos.otro recipiente y batir durante 5 minutos.
4.4.Calentar 2 minutosCalentar 2 minutos
5.5.Verter la mezcla 1 con la 2.Verter la mezcla 1 con la 2.
6.6.Dejar enfriar y servir.Dejar enfriar y servir.
Trataremos de explicar esto con el sgte. Ejemplo:El amigo Waldo quiere poner en práctica la siguiente receta:
Waldo advierte que hay varias formas de llevarlo a cabo: Waldo advierte que hay varias formas de llevarlo a cabo: 1. Un paso tras otro de tal forma que el siguiente no se 1. Un paso tras otro de tal forma que el siguiente no se completa hasta terminar el anterior, es decir en forma completa hasta terminar el anterior, es decir en forma SECUENCIALSECUENCIAL
Momento
Acciones
M1 1) Verter ingrediente uno y dos y batir 10 min.
M2 2) Dejar reposar 2 minutos.
M3 3) Mezclar ingredientes tres y cuatro y batir 5 min.
M4 4) Calentar 2 min.
M5 5) Verter mezcla 1 con la 2
M6 6) Dejar enfriar y servir
2. Un paso tras otro, pero si es posible, no es necesario 2. Un paso tras otro, pero si es posible, no es necesario que un paso anterior se haya concluido. Ejecución que un paso anterior se haya concluido. Ejecución CONCURRENTE.CONCURRENTE.
Momento Acciones
M1 1) Verter ingredientes uno y dos y batir durante 5 minutos (faltan 5 min. por batir)
M2 1) Mezclar ingredientes tres y cuatro y batir durante 3 minutos (faltan 2 min. por batir).
M3 1) Batir ingredientes uno y dos por los 5 minutos que faltan.
M4 1) Dejar reposar por 2 minutos2) Completar el batido por 2 minutos de los ingredientes
tres y cuatro.
M5 4) Calentar por 2 minutos.
M6 5) Verter mezcla 1 con la 2
M7 6) Dejar enfriar y servir
3. Waldo, se da cuenta que puede realizar la receta más 3. Waldo, se da cuenta que puede realizar la receta más rápido si pide ayuda a su amigo Arturo; así que lo rápido si pide ayuda a su amigo Arturo; así que lo llama y se reparten el trabajo de la siguiente llama y se reparten el trabajo de la siguiente manera: (ejecucion PARALELA)manera: (ejecucion PARALELA)
Mom. Acciones de Waldo Acciones de Arturo
M1 1) Verter ingrediente uno y dos en un recipiente y batir 10 minutos.
Mezclar el ingrediente tres y cuatro en otro recipiente y batir por 5 minutos.
M2 (continúa el paso 1) 1) Calentar 2 minutos
M3 1) Dejar reposar 2 min. (no hace nada)
M4 5) Verter la mezcla 1 con la dos
(no hace nada)
M5 (no hace nada) 6) Dejar enfriar y servir
EJECUCION SECUENCIALEJECUCION SECUENCIAL
Tiempo
P1
P2
EJECUCION CONCURRENTEEJECUCION CONCURRENTE
Tiempo
P1
P2
EJECUCION PARALELAEJECUCION PARALELA
P1
P2
Tiempo
ProcesadorProcesador
Es un dispositivo hardware capaz de Es un dispositivo hardware capaz de ejecutar las instrucciones de un proceso. ejecutar las instrucciones de un proceso. Un procesador puede ejecutar una sola Un procesador puede ejecutar una sola instrucción de un programa a la vez.instrucción de un programa a la vez.Existen computadores que tienen un solo Existen computadores que tienen un solo procesador y a los cuales se les denomina procesador y a los cuales se les denomina monoprocesadormonoprocesador y a las computadoras y a las computadoras que poseen varios procesadores se les que poseen varios procesadores se les llama llama multiprocesadormultiprocesador..
ProcesoProceso
Cuando el computador ejecuta un Cuando el computador ejecuta un conjunto de instrucciones, se dice que conjunto de instrucciones, se dice que esta realizando un proceso o tarea, por esta realizando un proceso o tarea, por lo que un proceso es una secuencia de lo que un proceso es una secuencia de instrucciones o sentencias que se instrucciones o sentencias que se ejecutan secuencialmente en un ejecutan secuencialmente en un procesadorprocesador
HiloHiloEn un entorno multitarea a las tareas se les En un entorno multitarea a las tareas se les llama procesos pesados, en un entorno llama procesos pesados, en un entorno multihilo se les denomina procesos ligeros o multihilo se les denomina procesos ligeros o hilos. La diferencia es que os procesos hilos. La diferencia es que os procesos pesados están en espacios de pesados están en espacios de direccionamiento distintos. La comunicación direccionamiento distintos. La comunicación entre procesos y el cambio de contexto es entre procesos y el cambio de contexto es muy caro. Por el contrario, los hilos comparten muy caro. Por el contrario, los hilos comparten el mismo espacio de direcciones y comparten el mismo espacio de direcciones y comparten cooperativamente el mismo proceso pesadocooperativamente el mismo proceso pesado
Proceso e HiloProceso e HiloProcesoPesado 1
ProcesoPesado 3
PROCESADOR
hilos
Estados de los procesosEstados de los procesos INICIAL
LISTO
EJECUCION
FINALIZADOBLOQUEADO
Creación
Ocurre Evento
Despachar Desalojar
Espera Evento Terminar
Ejecucion de los Ejecucion de los procesosprocesos Habiamos dicho queHabiamos dicho que en informatica se en informatica se
habla de concurrencia cuando hay una habla de concurrencia cuando hay una existencia simultánea de varios existencia simultánea de varios procesos en ejecuciónprocesos en ejecución..
Pero no se dijimos nada que si esos Pero no se dijimos nada que si esos procesos se ejecutan sobre un solo procesos se ejecutan sobre un solo procesador o varios procesadores.procesador o varios procesadores.
Para aclarar este concepto nos Para aclarar este concepto nos pondremos un ejemplo simple:pondremos un ejemplo simple:
Programacion Concurrente.Programacion Concurrente.Disciplina que se encarga del estudio de las notaciones que permiten especificar la ejecución concurrente de las acciones de un programa, así como las técnicas para resolver los problemas inherentes a la ejecución concurrente (comunicación y sincronización)
Programacion Concurrente.Programacion Concurrente. Tradicionalmente estuvo asociada al mundo de Tradicionalmente estuvo asociada al mundo de
losSistemas OperativoslosSistemas Operativos Primeros programas concurrentes:Primeros programas concurrentes:
✔ Diferentes partes del SO en ejecución sin un Diferentes partes del SO en ejecución sin un orden predecible y compartiendo variables orden predecible y compartiendo variables => nuevos problemas=> nuevos problemas
Tres hitos importantes marcan su evolución:Tres hitos importantes marcan su evolución:✔ HiloHilo✔ Aparición de lenguajes de alto nivel que da Aparición de lenguajes de alto nivel que da
soporte a la P.C.soporte a la P.C.✔ La aparición de InternetLa aparición de Internet
Programacion Concurrente.Programacion Concurrente. EL trabajar con procesos concurrentes EL trabajar con procesos concurrentes
añade complejidad a la tarea de añade complejidad a la tarea de programarprogramar
¿cuáles son entonces los beneficios que ¿cuáles son entonces los beneficios que aporta la programación concurrente?aporta la programación concurrente?
Beneficios de la Beneficios de la Programación ConcurrenteProgramación Concurrente Mejor aprovechamiento de la CPUMejor aprovechamiento de la CPU Velocidad de ejecuciónVelocidad de ejecución Solución de problemas de naturaleza Solución de problemas de naturaleza
concurrenteconcurrente Sistemas de controlSistemas de control Tecnologías webTecnologías web Sistemas de Tiempo RealSistemas de Tiempo Real SimulaciónSimulación SGDBSGDB
Características de los Características de los Programas ConcurrentesProgramas Concurrentes
Orden de ejecución de las instruccionesOrden de ejecución de las instrucciones
IndeterminismoIndeterminismo
Orden de Ejecución de las Orden de Ejecución de las instruccionesinstrucciones
La programación secuencial define un La programación secuencial define un orden orden total total de las instrucciones.de las instrucciones.
Ante un conjunto de datos de entrada, el flujo Ante un conjunto de datos de entrada, el flujo de ejecución es siempre el mismo.de ejecución es siempre el mismo.
Ejemplo: P, QEjemplo: P, Q✗ P: < p1 P: < p1 p2 p3 ... pm > p2 p3 ... pm >✗ Q: < q1 Q: < q1 q2 q3 ... qn > q2 q3 ... qn >
SecuencialSecuencial < p1 < p1 p2 p2 p3 p3 ... ... pm q1 pm q1 q2 q2 q3 q3 ... ...
qn >qn >
Orden de Ejecución de las Orden de Ejecución de las instruccionesinstrucciones Un programa concurrente define un Un programa concurrente define un
orden parcial orden parcial de ejecución.de ejecución. Ante un conjunto de datos de entrada no Ante un conjunto de datos de entrada no
se puede saber cual va a ser el flujo de se puede saber cual va a ser el flujo de ejecución.ejecución.
IndeterminismoIndeterminismo El orden parcial implica el El orden parcial implica el nono determinismo determinismo de los programas concurrentes.de los programas concurrentes.
Es decir, puede producir diferentes Es decir, puede producir diferentes resultados cuando se ejecuta repetidamente resultados cuando se ejecuta repetidamente sobre el mismo conjunto de datos de sobre el mismo conjunto de datos de entrada.entrada.
El no determinismo es una propiedad El no determinismo es una propiedad inherente a la concurrenciainherente a la concurrencia
Por culpa del no determinismo, es más difícil Por culpa del no determinismo, es más difícil analizar y verificar un algoritmo concurrenteanalizar y verificar un algoritmo concurrente
Ojo, que existan varias posibilidades de Ojo, que existan varias posibilidades de salida NO significa salida NO significa necesariamente necesariamente que un que un programa concurrente sea incorrecto.programa concurrente sea incorrecto.
Peculiaridades de los Peculiaridades de los programas concurrentesprogramas concurrentes Los programas concurrentes pueden no Los programas concurrentes pueden no
terminar nunca y al mismo tiempo ser terminar nunca y al mismo tiempo ser correctos.correctos.
Unprograma concurrente puede tener Unprograma concurrente puede tener múltiples secuencias de ejecución.múltiples secuencias de ejecución.
Cuando se dice que un programa Cuando se dice que un programa concurrente es correcto, seentiende que concurrente es correcto, seentiende que se refiere a todas sus posibles se refiere a todas sus posibles secuencias de ejecución.secuencias de ejecución.
secuencias de ejecuciónsecuencias de ejecución
Problemas inherentes a la Problemas inherentes a la Programación ConcurrenteProgramación Concurrente
Exclusión MutuaExclusión Mutua Condición de SincronizaciónCondición de Sincronización Verificación.Verificación.
Exclusión MutuaExclusión Mutua Si dos hilos P1 y P2 utilizan una variable Si dos hilos P1 y P2 utilizan una variable
compartida X, y ambos desean realizar compartida X, y ambos desean realizar alguna actualización de ésta en alguna alguna actualización de ésta en alguna parte de su código, tendríamos:parte de su código, tendríamos:
Hilo P1 Hilo P2 inicioinicio inicio X <-- 0 .... .... P1 X <-- X+1 X <-- X+1 P2 .... .... ....fin fin JuntarHilos
escribir Xfin
¿Cuál será el resultado?
Exclusión MutuaExclusión Mutua¿en que consiste el ¿en que consiste el problema?problema?Un lenguaje de alto nivel facilita la programación mediante la abstracción de operaciones máquina en operaciones de alto nivel. Asi, una operación como:
A:= A+1
se traduce en el siguiente conjunto de operaciones atómicas.
LOAD A, RADD R, 1STORE R, A
Exclusión MutuaExclusión MutuaEn la ejecución del ejemplo podría darse el siguiente escenario:
P1: LOAD RP1,XP2: LOAD RP2,XP1: ADD RP1,1P2: ADD RP2,1P1: STORE RP1,XP2: STORE RP2,X
por lo que el resultado del programa podría ser incorrecto.
Sección CríticaSección CríticaPorción de código con variables compartidas y que debe ejecutarse en exclusión mutua.Los lenguajes concurrentes deben proporcionar herramientas para resolver este tipo de problemas
Exclusión MutuaExclusión Mutua
Problema derivado de la abstracción en Problema derivado de la abstracción en los lenguajes de alto nivellos lenguajes de alto nivel
Una instrucción de alto nivel se convierte Una instrucción de alto nivel se convierte en un conjunto de instrucciones en un conjunto de instrucciones máquina, éstas son las que realmente se máquina, éstas son las que realmente se ejecutan concurrentemente.ejecutan concurrentemente.
En el paradigma secuencial este hecho En el paradigma secuencial este hecho carece de importancia pero en carece de importancia pero en ejecuciones concurrentes el resultado ejecuciones concurrentes el resultado puede ser incorrecto.puede ser incorrecto.
Exclusión MutuaExclusión Mutua
Garantía de que un único proceso o hilo accede Garantía de que un único proceso o hilo accede a un recurso en un determinado instantea un recurso en un determinado instante
Exclusión MutuaExclusión Mutua
Solución general:
inicio ..... ..... <Fase de negociación> Sección – Crítica <Fase de liberación>
......
......fin
Soluciones de la Exclusión Soluciones de la Exclusión MutuaMutua Primer Algoritmo
Hilo P1inicio mientras true hacer inicio {sección no crítica} repetir
hasta que acceso=1 {sección crítica} acceso=2 finfin
Hilo P1inicio mientras true hacer inicio {sección no crítica} repetir
hasta que acceso=1 {sección crítica} acceso=2 finfin
acceso: entero en el rango 1..2 con valor inicial 1
Primer algoritmo Primer algoritmo (comentario)(comentario)
La solución anterior es incorrecta porque ambos procesos examinan y actualizan una única variable global. Así, si uno de los procesos “muere” se producirá una situación de bloqueo en el otro.
Para solventar esta situación, podemos pensar en que cada proceso actúe sobre su propia variable, como se muestra en la figura siguiente.
Soluciones de la Exclusión Soluciones de la Exclusión MutuaMutuaSegundo Algoritmo
Hilo P1inicio mientras true hacer inicio {sección no crítica} repetir
hasta que C2=1 C1=0 {sección crítica} C1=1 finfin
Hilo P1inicio mientras true hacer inicio {sección no crítica} repetir
hasta que C1=1 C2=0 {sección crítica} C2=1 finfin
C1, C2: entero en el rango 0..1 con valor inicial 1
Segundo Algoritmo Segundo Algoritmo (comentario)(comentario)Cada proceso Pi asigna a la variable Ci el valor 0 cuando desea entrar en su sección crítica y el valor 1 Ci cuando la ha concluido. De esta manera, mientras un proceso no está en su sección crítica el valor de las variables de control es 1, con lo que si el proceso entra en un estado de halt el resto puede seguir trabajando. Ahora bien, aunque este segundo algoritmo garantiza la ausencia de bloqueos,no existe exclusión mutua, ya que los dos procesos pueden alcanzar sus secciones críticas simultáneamente.En la figura anterior, cuando un proceso concluye el bucle de espera, inicia una secuencia de instrucción que permiten alcanzar sin ninguna prevención su sección crítica. Este conjunto de acciones puedne no ser, no lo son de hecho, atómicas. Por tanto el error está en no considerar las actuaciones sobre las variables de control como sección crítica.Para solucionarlo se puede utilizar el siguiente algoritmo,
Soluciones de la Exclusión Soluciones de la Exclusión MutuaMutuaTercer Algoritmo
Hilo P1inicio mientras true hacer inicio {sección no crítica} C1=0 repetir
hasta que C2=1 {sección crítica} C1=1 finfin
Hilo P2inicio mientras true hacer inicio {sección no crítica} C2=0 repetir
hasta que C1=1 {sección crítica} C2=1 finfin
C1, C2: entero en el rango 0..1 con valor inicial 1
Soluciones de la Exclusión Soluciones de la Exclusión MutuaMutuaHilo P1inicio mientras true hacer inicio {sección no crítica} C1=0 repetir C1=1 C1=0 hasta que C2=1 {sección crítica} C1=1 finfin
Hilo P2inicio mientras true hacer inicio {sección no crítica} C2=0 repetir C2=1 C2=0 hasta que C1=1 {sección crítica} C2=1 finfin
Cuarto Algoritmo
Algoritmo de DekkerAlgoritmo de DekkerHilo p1inicio {sección no crítica} C1 = 0 repetir if Acceso = 2 entonces inicio C1 = 1 repetir hasta Acceso = 1 C1 = 0 fin hasta que C2 = 1 {sección critica} C1 = 1 Acceso = 2fin
Hilo p2inicio {sección no crítica} C2 = 0 repetir if Acceso = 1 entonces inicio C2 = 1 repetir hasta Acceso = 2 C2 = 0 fin hasta que C1 = 1 {sección critica} C2 = 1 Acceso = 1fin
C1, C2: enteros en el rango 0..1 con valor inicial 1Acceso: entero en el rango 1..2 con valor inicial 1
Propiedades de la Propiedades de la Programación ConcurrenteProgramación Concurrente Propiedades de seguridad (safety)Propiedades de seguridad (safety)
Exclusión mutuaExclusión mutua El acceso con exclusión mutua a secciones El acceso con exclusión mutua a secciones
críticas esta garantizadocríticas esta garantizado SincronizaciónSincronización
los procesos cumplen con las condiciones los procesos cumplen con las condiciones de sincronización impuestos por el de sincronización impuestos por el algoritmo algoritmo
Interbloqueo (pasivo) – deadlockInterbloqueo (pasivo) – deadlock no se produce una situación en la cual no se produce una situación en la cual
todos los procesos participantes quedan todos los procesos participantes quedan atrapados en una espera a una condición atrapados en una espera a una condición que nunco se cumpla. que nunco se cumpla.
Propiedades de la Propiedades de la Programación ConcurrenteProgramación Concurrente Propiedades de vivacidad (liveness)Propiedades de vivacidad (liveness)
Interbloqueo (activo) – livelockInterbloqueo (activo) – livelock puede ocurrir el caso que varios procesos puede ocurrir el caso que varios procesos
están continuamente competiendo por un están continuamente competiendo por un recurso de forma activa, pero ningúno de recurso de forma activa, pero ningúno de ellos lo consigue (``livelock'') ellos lo consigue (``livelock'')
Inanición – starvationInanición – starvation un proceso puede ``morirse'' por inanición un proceso puede ``morirse'' por inanición
(``starvation''), es decir, un proceso o varios (``starvation''), es decir, un proceso o varios procesos siguen con su trabajo pero otros procesos siguen con su trabajo pero otros nunca llegan a utilizar los recursos por ser nunca llegan a utilizar los recursos por ser excluido de la competición por los recursosexcluido de la competición por los recursos
MECANISMOS DE MECANISMOS DE COMUNICACION Y COMUNICACION Y SINCRONIZACIONSINCRONIZACION SEMAFOROSSEMAFOROS REGIONES CRITICAS CONDICIONALESREGIONES CRITICAS CONDICIONALES MONITORESMONITORES MENSAJESMENSAJES
SEMAFOROSSEMAFOROS
Es un mecanismo introducido por Es un mecanismo introducido por Dijkstra y su aplicación permite Dijkstra y su aplicación permite controlar el acceso exclusivo a controlar el acceso exclusivo a recursos compartidosrecursos compartidos
Su aplicación tambien permite la Su aplicación tambien permite la sincronización entre procesossincronización entre procesos
Esta formado de un contador y una Esta formado de un contador y una cola asociada de procesos o hilos en cola asociada de procesos o hilos en esperaespera
Las operaciones básica sobre el Las operaciones básica sobre el contador son Wait o P y Signal o Vcontador son Wait o P y Signal o V
TAD SemaforoTAD SemaforoNombre del TAD: SemaforoDescripción Genérica del TAD:
Un semáforo es un tipo de datos abstracto que permite el uso de un recurso de manera exclusiva cuando varios procesos están compitiendo.
Descripción Formal del TAD
Nombre: Semaforo
Elementos:
Semaforo(entero, lista)
Donde:
entero: contador del semaforo, numero entero mayor o igual a 0
lista : lista de procesos o hilos.
TAD SemaforoTAD SemaforoConjunto de Operaciones: Semaforo (lista) ------> Semaforo Semaforo (entero x lista) ------> Semaforo Wait ------> Lista Signal ------> ListaDescripción de las Operaciones: Constructores. Semaforo (lista) : crea un semaforo con valor inicial 0 Semaforo (entero x lista) : crea un semaforo con un valor inicial
mayor a cero
TAD SemaforoTAD Semaforo
Operaciones Primitivas. Wait : si el contador del semáforo es igual a 0 entonces se lleva el proceso que realiza la operación a la cola asociada con el semáforo suspendiendo su ejecución y abandonando el procesador a favor de otro proceso sino se decrementa el valor del contador del semaforo en
una unidad y el proceso que realiza la operación sigue ejecutándose. Esta operación debe ser indivisible
TAD SemaforoTAD Semaforo
Signal : se incrementa el valor del contador del semaforo en una unidad . Esta operación debe ser indivisible.Se toma uno de los procesos que esperan en la cola delsemáforo (si hubira) y se le pone en un estado de preparado para ejecutarse. El proceso que realiza la operación sigueejecutándose
SemaforosSemaforosSolución al Problema de la exclusión mutua
Hilo P1inicio mientras verdad hacer inicio {sección no crítica} wait(mutex) {sección crítica} signal(mutex) finfin
Hilo P2inicio mientras verdad hacer inicio {sección no crítica} wait(mutex) {sección crítica} signal(mutex) finfin
Tipos de SemáforosTipos de Semáforos
Semáforos binarios.Semáforos binarios. Toman valores de 0, 1Toman valores de 0, 1
Semáforos generales.Semáforos generales. Toman valores de 0,1,2,3,4.....nToman valores de 0,1,2,3,4.....n
EjemplosEjemplosProblema de Productores y Problema de Productores y consumidoresconsumidores
PROCESO productoresVAR pdato : dato;inicio mientras true hacer inicio wait(producir); pdato := producir(); wait(ps); buffer[ent]:= pdato; ent := (ent mod MAX) + 1; signal(ps); signal(consumir); finfin; (* Productores *)
PROCESO consumidores;VAR cdato : dato;inicio mientras true hacer inicio wait(consumir); wait(cs); cdato:= buffer[sal]; sal := (sal mod MAX) + 1; signal(cs); signal(producir); consumir(cdato); finfin; (* Consumidores *)
Inicio {programa principal}CONSMAX = .. ; (* Cap. Buffer *)TYPEdato: .. ; (* Tipo de datos*)VARbuffer :array[1..MAX]of dato;producir, consumir:semaforo;ps, cs: semaforo;ent, sal: integer;
initial(ps,1); initial(cs,1); initial(consumir,0); initial(poducir,MAX); ent:=1; sal:=1; {ejecutar concurrentemente} productores; consumidores fin. (* principal *)
top related