Tema 3: MONITORES - Departamento de Lenguajes y Sistemas ...
Tema 3: MONITORES - Departamento de Lenguajes y Sistemas ...
Tema 3: MONITORES - Departamento de Lenguajes y Sistemas ...
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>Tema</strong> 3. Monitores<br />
Programación Concurrente<br />
Depto. <strong>de</strong> <strong>Lenguajes</strong> y <strong>Sistemas</strong> Informáticos<br />
Universidad <strong>de</strong> Granada
Contenidos<br />
1. Concepto <strong>de</strong> Monitor<br />
1.1. Fundamento teórico <strong>de</strong> los monitores<br />
1.2. Sintaxis <strong>de</strong> los monitores<br />
1.3. Exclusión mutua con monitores<br />
1.4. Instanciación <strong>de</strong> monitores<br />
2. Sincronización en Monitores<br />
2.1. Primitivas <strong>de</strong> sincronización en monitores<br />
2.2. Efecto <strong>de</strong> las operaciones sincronización sobre la exclusión<br />
mutua <strong>de</strong>l monitor<br />
2.3. Equivalencia entre semáforos y monitores<br />
2.4. Problemas paradigmáticos resueltos con monitores
1. Concepto <strong>de</strong> Monitor<br />
1.1. Fundamento teórico <strong>de</strong> los monitores<br />
• Inconvenientes mecanismos como los semáforos:<br />
– Basados en variables globales → No modular.<br />
– Uso y función <strong>de</strong> las variables no explícito.<br />
– Operaciones sobre variables recurso dispersas y no protegidas.<br />
• No Acceso estructurado ni encapsulación → Fuente <strong>de</strong> errores.<br />
• Monitor (Hoare 1974) : Mecanismo <strong>de</strong> alto nivel que permite<br />
– Definir objetos abstractos compartidos (una colección <strong>de</strong> datos y procedimientos<br />
asociados que se comparten por varios procesos).<br />
– Garantizar acceso exclusivo a datos e implementar sincronización.<br />
• Monitor = Encapsulación<br />
– Definición recurso (datos).<br />
– Operaciones <strong>de</strong> Manipulación (procedims.)<br />
• Recurso: Se percibe como un módulo al que se acce<strong>de</strong> concurrentemente.<br />
– El usuario ignora <strong>de</strong>talles <strong>de</strong> implementación <strong>de</strong>l recurso y <strong>de</strong> las<br />
operaciones asociadas.
1. Concepto <strong>de</strong> Monitor<br />
1.1.1. Centralización <strong>de</strong> funciones críticas.<br />
• Origen: S.O. concurrente → Monitor monolítico → Programa que centraliza las<br />
funciones críticas (asig./planif. recursos) <strong>de</strong>l sistema.<br />
• Soportados por facilida<strong>de</strong>s hardware:<br />
– Ejecución en modo ininterrumpido (E.M.).<br />
– Acceso a posiciones <strong>de</strong> memoria privilegiadas.<br />
– Ejecución <strong>de</strong> instrucciones privilegiadas.<br />
• Monitor: Versión “<strong>de</strong>scentralizada” <strong>de</strong>l monitor original.<br />
• Cada monitor tiene:<br />
– Una función específica.<br />
– Datos e instrucciones propias.<br />
• Ejemplo:<br />
– M1 : único monitor que acce<strong>de</strong> a v1 → asegura E.M. ya que será<br />
ininterrumpible (la entrada al monitor <strong>de</strong> un proceso excluye la entrada <strong>de</strong><br />
otros).<br />
– Único procesamiento sobre v1 programado en M1.<br />
• Diferentes monitores (o instancias <strong>de</strong> un monitor) para diferentes tareas.<br />
– Mayor Eficiencia (+ Concurrencia)<br />
– Mayor Robustez: Modularidad
1. Concepto <strong>de</strong> Monitor<br />
1.1.2. Estructuración en el acceso a los datos.<br />
• Definición tipos para las operaciones y los datos (T.A.D.).<br />
• Paradigma <strong>de</strong> Programación Modular:<br />
– Módulo: Conjunto <strong>de</strong> procedimientos relacionados + datos.<br />
– Principio <strong>de</strong> Ocultación <strong>de</strong> datos: Hacer local al módulo todo lo<br />
que no <strong>de</strong>be ser visible.<br />
• Ejemplo: Módulo <strong>de</strong> pila. Resolver:<br />
– Interfaz <strong>de</strong> usuario: procedimientos push y pop.<br />
– Representación (p.e. array) sólo accedida mediante interfaz.<br />
– Inicialización antes <strong>de</strong> uso.<br />
• <strong>Lenguajes</strong> <strong>de</strong> Programación Dirigida a Objetos → Clase.
1. Concepto <strong>de</strong> Monitor<br />
1.2. Sintaxis <strong>de</strong> los monitores<br />
Estructura <strong>de</strong> un monitor <strong>de</strong> nombre name y procedimientos<br />
op1,...,opN:<br />
Monitor name;<br />
var<br />
... Declaración <strong>de</strong> variables permanentes<br />
procedure op1 (...);<br />
var<br />
... Declaración <strong>de</strong> variables locales a op1<br />
{ ... Código que implementa op1 }<br />
... ... ...<br />
procedure opN (...);<br />
var<br />
... Declaración <strong>de</strong> variables locales a opN<br />
{ ... Código que implementa opN }<br />
begin<br />
end.<br />
... Código para inicializar variables permanentes
1. Concepto <strong>de</strong> Monitor<br />
1.2.1. Protección <strong>de</strong> los datos en el monitor.<br />
• Ámbito variables permanentes <strong>de</strong>l monitor : Código monitor<br />
(procedimientos y cod. inicialización).<br />
• Acceso variables permanentes: sólo <strong>de</strong>ntro <strong>de</strong> los<br />
procedimientos.<br />
• Procedimientos sólo acce<strong>de</strong>n:<br />
– Variables permanentes<br />
– Variables locales<br />
• Valores variables permanentes se mantienen entre diferentes<br />
ejecuciones <strong>de</strong> los procedimientos.<br />
• Comunicación monitor-mundo exterior: A través <strong>de</strong> los<br />
parámetros <strong>de</strong> los procedimientos.
1. Concepto <strong>de</strong> Monitor<br />
1.2.2. Procedimientos <strong>de</strong>l Monitor.<br />
• Comunes a todos los procesos <strong>de</strong>l sistema.<br />
• Nueva llamada proced. → Nuevos valores parámetros y<br />
variables locales.<br />
• Sintaxis:<br />
nombremonitor.nombreprocedimiento(parámetros_reales);<br />
1.2.3. Código <strong>de</strong> inicialización<br />
• Ejecución sólo 1 vez: Inicializa vars. Permanentes.<br />
• Tras Ejecución: Monitor = objeto pasivo (datos + proceds.)<br />
• Única forma ejecutar monitor: llamar proced.
1. Concepto <strong>de</strong> Monitor<br />
1.3. Exclusión mútua con monitores<br />
• Acceso al monitor en E.M.<br />
– Sólo un proceso en un momento dado pue<strong>de</strong> ejecutar un procedimiento<br />
• Subsiguientes llamadas esperan finalización.<br />
– Violación podría tener efectos caóticos sobre vars.<br />
• Ventajas sobre Semáforos (soluc. no estructurada):<br />
– Protección Variables: evita interferencias exteriores<br />
– Estructuración acceso: Espera y señalización se programan <strong>de</strong>ntro monitor. Si<br />
el monitor es correcto, lo será cada instancia utilizada por los procesos.<br />
– E.M. garantizada automáticamente → No errores.<br />
• Invariante: Define una relación sobre los datos <strong>de</strong>l monitor.<br />
– Se mantiene siempre excepto cuando un procedimiento está ejecutándose.<br />
– Se ha <strong>de</strong> cumplir antes <strong>de</strong> entrar y <strong>de</strong>spués <strong>de</strong> salir.<br />
– Se ha <strong>de</strong> reestablecer el invariante en procedimientos antes <strong>de</strong> <strong>de</strong>volver el<br />
control o suspen<strong>de</strong>r el proceso.
1. Concepto <strong>de</strong> Monitor<br />
1.4. Instanciación <strong>de</strong> monitores<br />
• Permite <strong>de</strong>clarar diversos monitores con estructura y<br />
comportamiento idénticos (Ej.: planificar varios recursos<br />
similares).<br />
• Declaración tipo monitor:<br />
Class Monitor nombre_clase<br />
.... .......<br />
• Instanciación <strong>de</strong> monitores: monitor1, monitor2: nombreclase;<br />
• Práctica: se permite <strong>de</strong>clarar varias instancias e incluso<br />
conjuntos parametrizados <strong>de</strong> monitores.<br />
• Implementación con procedimientos reentrantes:<br />
– Basta asignar nuevas instancias <strong>de</strong> las variables globales<br />
para cada instancia <strong>de</strong> un monitor.
2. Sincronización en Monitores<br />
2.1. Primitivas <strong>de</strong> sincronización en monitores<br />
• Sincronización: Facilidad <strong>de</strong> bloqueo-activación <strong>de</strong> acuerdo<br />
a una condición.<br />
• Propósitos <strong>de</strong> las instrucciones <strong>de</strong> sincronización en<br />
semáforos:<br />
– Bloqueo-activación<br />
– Cuenta (representación condición)<br />
• En monitores:<br />
– Sólo Bloqueo-activación<br />
– Representación condición mediante datos protegidos <strong>de</strong>l<br />
monitor
2. Sincronización en Monitores<br />
2.1. Primitivas <strong>de</strong> sincronización en monitores (cont.)<br />
• Ejemplo <strong>de</strong> monitor: Planificador <strong>de</strong> un único recurso (sem. binario)<br />
monitor recurso;<br />
var ocupado: boolean;<br />
noocupado: condicion;<br />
procedure adquirir;<br />
{if ocupado then noocupado.wait; ocupado := true}<br />
procedure liberar;<br />
{ocupado := false; noocupado.signal;}<br />
begin<br />
ocupado := false /* valor inicial*/<br />
end;
2. Sincronización en Monitores<br />
2.1.1. Semántica <strong>de</strong> las operaciones<br />
●<br />
Wait: "estoy esperando a que algo (condición) ocurra".<br />
– Bloquea proceso.<br />
●<br />
Signal: "estoy señalando que algo (condición) ha ocurrido".<br />
– Reactiva un proceso bloqueado en esa condición.<br />
• Responsabilidad <strong>de</strong>l programador→ que el proceso ejecute:<br />
– Wait: cuando algo (condición) no se dé<br />
– Signal: Cuando la condición acabe <strong>de</strong> activarse.
2. Sincronización en Monitores<br />
2.1.2. Variables <strong>de</strong> condición o señales<br />
• Más <strong>de</strong> una razón para esperar:<br />
– representan distintas condiciones<br />
– Deben <strong>de</strong> ser diferenciadas por wait y signal.<br />
• Nuevo tipo <strong>de</strong> variable:<br />
– Variable <strong>de</strong> condición o señal. Sin valor almacenado (ni V, ni F).<br />
– Una variable condición por cada razón <strong>de</strong> bloqueo.<br />
• Operaciones<br />
Nombre_variable_condición.wait<br />
Nombre_variable_condición.signal<br />
• Representación variable condición<br />
– Cola (inicialmente vacía) <strong>de</strong> procs esperando en condición. Invisible<br />
a procs.<br />
• Más <strong>de</strong> un proceso pue<strong>de</strong> estar <strong>de</strong>ntro <strong>de</strong>l mismo monitor, aunque sólo<br />
uno ejecutándose (resto bloqueados en variables condición).
2. Sincronización en Monitores<br />
2.1.3. Propiedad FIFO <strong>de</strong> las colas <strong>de</strong> condición<br />
• Más <strong>de</strong> un proc. esperando en condición →<br />
– condición.signal reactivará el proc. que lleve más tiempo<br />
esperando.<br />
• Cada proc. en cola obtendrá eventualmente su turno → No<br />
inanición.<br />
●<br />
condición.queue<br />
– Función booleana = V → Hay algún proc. esperando en<br />
condición.
2. Sincronización en Monitores<br />
2.1.4. Colas <strong>de</strong> condición con prioridad<br />
• Propiedad FIFO: evita inanición.<br />
• Mayor control sobre estrategia <strong>de</strong> planificación: prioridad <strong>de</strong>l proceso<br />
en espera como nuevo parámetro.<br />
• Formato: Nombre_var_condición.wait (prioridad:integer);<br />
• Signal reanuda proceso que especificó el valor más bajo <strong>de</strong> prioridad.<br />
• Precaución diseño monitor: Evitar riesgos como la inanición.<br />
• Justificación:<br />
– Ningún efecto sobre la lógica <strong>de</strong>l programa: Funcionamiento<br />
similar con/sin colas <strong>de</strong> prioridad. Sólo mejora características <strong>de</strong>p.<br />
<strong>de</strong>l tiempo.<br />
– Or<strong>de</strong>nación automática cola: técnica <strong>de</strong> planificación rápida y<br />
sencilla, excepto si la cola es muy larga.<br />
– Almacenamiento requerido por proceso: una palabra
2. Sincronización en Monitores<br />
2.1.4. Colas <strong>de</strong> condición con prioridad (cont.)<br />
Ejemplo: Reloj con alarma. El proc. llamador se retarda n unida<strong>de</strong>s <strong>de</strong><br />
tiempo.<br />
monitor <strong>de</strong>spertador;<br />
var ahora: integer; <strong>de</strong>spertar: condicion;<br />
procedure <strong>de</strong>spiertame (n: integer);<br />
var alarma: integer;<br />
{alarma := ahora + n; while ahora
2. Sincronización en Monitores<br />
2.1.4. Colas <strong>de</strong> condición con prioridad (cont.)<br />
Ejemplo: Asignación recurso "siguiente trabajo el más corto".<br />
monitor asignador;<br />
var libre: boolean; turno: condicion;<br />
procedure petición (tiempo: integer);<br />
{if not libre then turno.wait (tiempo); libre:=false;}<br />
procedure liberar;<br />
{libre := true; turno.signal;}<br />
begin<br />
libre:= true;<br />
end;
2. Sincronización en Monitores<br />
2.2. Efecto <strong>de</strong> las operaciones <strong>de</strong> sincr. sobre la E.M. <strong>de</strong>l monitor<br />
• Requisito <strong>de</strong> reanudación inmediata<br />
– Un Signal <strong>de</strong>berá ir seguida inmediatamente por la reanudación <strong>de</strong> un proceso en espera,<br />
sin que exista la posibilidad <strong>de</strong> que intervenga la llamada a un procedimiento <strong>de</strong> un tercer<br />
proceso.<br />
• Única forma <strong>de</strong> garantizar que procesos en espera puedan adquirir un recurso que<br />
acaba <strong>de</strong> ser liberado → Evita inanición.<br />
• Propuesta <strong>de</strong> Hoare<br />
– Un proceso suspendido <strong>de</strong>bido a ejecución <strong>de</strong> signal, entrará en una cola <strong>de</strong> suspendidos<br />
en Signal. Cada proceso antes <strong>de</strong> salir <strong>de</strong>l monitor y liberar la E.M., comprueba si hay<br />
procesos en esta cola, si los hay, heredarán la E.M. Los procesos suspendidos al ejecutar<br />
una operación signal tienen prioridad sobre los que intentan entrar.<br />
• Propuesta <strong>de</strong> Brinch-Hansen<br />
– Signal sólo como última instrucción <strong>de</strong>l cuerpo.<br />
– Evita cola <strong>de</strong> suspendidos en signal → + Eficiencia
2. Sincronización en Monitores<br />
2.2.1. Problema <strong>de</strong> Anidación <strong>de</strong> llamadas en monitores<br />
• Sistema estructurado como colección jerárquica <strong>de</strong> monitores:<br />
procs. <strong>de</strong> un monitor pue<strong>de</strong>n llamar a otro<br />
• Problema:<br />
– Una llamada <strong>de</strong> monitor anidada se suspen<strong>de</strong> en el último monitor. La<br />
E.M. en el último se abandonará pero no en el monitor <strong>de</strong>s<strong>de</strong> el que<br />
se llama.<br />
– Los procesos que intenten llamar a procedimientos <strong>de</strong> cualquier<br />
monitor <strong>de</strong> la ca<strong>de</strong>na se bloquearán.<br />
– Menor concurrencia → Menor rendimiento.
2. Sincronización en Monitores<br />
2.2.1.1. Problema <strong>de</strong> Anidación. Propuestas <strong>de</strong> solución<br />
a) Prohibir llamadas anidadas.<br />
b) Liberar exclusión mútua en todos los monitores implicados en la ca<strong>de</strong>na y bloquear<br />
proceso.<br />
– Una vez señalado, el proceso necesitará readquirir el acceso exclusivo a todos los<br />
monitores.<br />
– Requerirá que el invariante <strong>de</strong>l monitor se establezca antes <strong>de</strong> cualquier llamada que<br />
pueda bloquear.<br />
c) Monitores = herramienta <strong>de</strong> estructuración para recursos compartidos. E.M. →<br />
sólo forma <strong>de</strong> preservar integridad <strong>de</strong>l recurso.<br />
– Hay casos en los cuales las operaciones <strong>de</strong> un monitor pue<strong>de</strong>n ejecutarse<br />
concurrentemente sin efectos adversos.<br />
– Definir construcción que permita especificar que ciertas operaciones se podrán ejecutar<br />
concurrentemente y la exclusión mútua se liberará.
2. Sincronización en Monitores<br />
2.3. Equivalencia entre semáforos y monitores<br />
• Los monitores pue<strong>de</strong>n ser implementados por semáforos.<br />
• Garantizar la E.M.<strong>de</strong> los cuerpos los procedimientos<br />
– Para cada monitor → Semáforo binario mutex (inic. a 1) para asegurar<br />
exclusión mútua entre los cuerpos <strong>de</strong> procedimientos.<br />
• mutex:bin_sem=1<br />
• ENTRADA Proc. → P(mutex)<br />
• SALIDA<br />
Proc. → Normalmente V(mutex)
2. Sincronización en Monitores<br />
2.3. Equivalencia entre semáforos y monitores (cont.)<br />
Propuesta <strong>de</strong> Hoare:<br />
– Semáforo urgente (inic. a 0) para cola <strong>de</strong> bloqueados en Signal<br />
– Contador procs. esperando en urgente (conturgente, inic. a 0).<br />
• Procesos que invocan un signal ejecutan:<br />
if (existen procs. bloqueados en wait) { conturgente ++;<br />
P(urgente) }<br />
• Para liberar procs. bloqueados en signal, antes <strong>de</strong> liberar la<br />
exclusión mútua, cada proceso ejecuta:<br />
if conturgente>0 V(urgente)<br />
else V(mutex);
2. Sincronización en Monitores<br />
2.3. Equivalencia entre semáforos y monitores (cont.)<br />
• Para cada variable condición <strong>de</strong>l monitor:<br />
– Semáforo semcondición (inic. a 0) para cola <strong>de</strong> bloqueados en Wait<br />
– Contador <strong>de</strong> nº procs. esperando condición (contcondición inic. a 0).<br />
condición.signal<br />
conturgente + +;<br />
if contcondición>0<br />
{ V(semcondición);<br />
P(urgente); }<br />
conturgente - - ;<br />
condición.wait<br />
contcondición + +;<br />
if conturgente>0<br />
V(urgente)<br />
else V(mutex);<br />
P(semcondición);<br />
contcondición - -;
2. Sincronización en Monitores<br />
2.3.1. Equivalencia entre semáforos y monitores. Mejoras<br />
• Salida <strong>de</strong>l cuerpo <strong>de</strong> un procedimiento sin wait ni signal V(mutex)<br />
– conturgente no ha cambiado.<br />
• Salida cuando signal es la última instrucción <strong>de</strong>l cuerpo:<br />
if contcondición > 0 V(semcondición)<br />
(*) else if conturgente>0 V(urgente)<br />
else V(mutex);<br />
• No hay otro wait o signal en el cuerpo (*) pue<strong>de</strong> omitirse.<br />
• Propuesta <strong>de</strong> Brinch-Hansen<br />
– signal última operación <strong>de</strong>l cuerpo conturgente y urgente se omiten<br />
– Esta simplificación sugiere que todas las operaciones signal <strong>de</strong>berían siempre<br />
ser la última operación <strong>de</strong> un proc. <strong>de</strong>l monitor.
2. Sincronización en Monitores<br />
2.3.2. Semáforos v.s. Monitores<br />
• Equivalentes en potencia expresiva.<br />
• Motivación <strong>de</strong> uso Monitores: Claridad y fiabilidad.<br />
• Característica que no se pue<strong>de</strong> implementar en semáforos:<br />
Suposición FIFO sobre la cola.
2. Sincronización en Monitores<br />
2.4. Problemas paradigmáticos resueltos con monitores<br />
2.4.1. Productor/consumidor utilizando un buffer circular<br />
program productorconsumidor;<br />
monitor buffercircular;<br />
CONST tamaño=...;<br />
VAR b:array [0..tamaño-1] of integer; in, out, n: integer; novacio, nolleno:<br />
condicion;<br />
procedure añadir (v:integer);<br />
{if (n==tamaño) nolleno.wait; /* Espera a que no esté lleno*/<br />
b[in] = v; in = (in + 1) % tamaño; n ++; novacio.signal;}<br />
procedure tomar(var v:integer);<br />
{if (n==0) novacio.wait; /* Espera a que no esté vacío */<br />
v = b[out]; out = (out + 1) % tamaño; n --; nolleno.signal;}<br />
{in = out = n = 0}
2. Sincronización en Monitores<br />
2.4.1. Productor/consumidor utilizando un buffer circular (cont.)<br />
procedure productor;<br />
VAR v: integer;<br />
{while (true) {producir(v);añadir(v)}<br />
procedure consumidor;<br />
VAR v:integer;<br />
{while (true) {tomar(v);consumir(v) }<br />
{ cobegin /* programa principal*/<br />
productor; consumidor;<br />
coend; }
2. Sincronización en Monitores<br />
2.4.2.Problema <strong>de</strong> los lectores/escritores sin priorida<strong>de</strong>s (FIFO).<br />
program lectoresescritores;<br />
monitor leerescribir;<br />
VAR lectores: integer; escribiendo: boolean; okleer, okescribir: condicion;<br />
procedure comenzarleer;<br />
{if (escribiendo or okescribir.queue) okleer.wait;<br />
lectores + +; okleer.signal}<br />
procedure finleer; {lectores - -; if (lectores==0) okescribir.signal;}<br />
procedure comenzarescribir;<br />
{if (lectores!=0 or escribiendo) okescribir.wait;<br />
escribiendo= true }<br />
procedure finescribir;<br />
{escribiendo = false; if (okleer.queue) okleer.signal else okescribir.signal }<br />
{lectores =0;<br />
escribiendo = false}
2. Sincronización en Monitores<br />
2.4.2.Problema <strong>de</strong> los lectores/escritores sin priorida<strong>de</strong>s (FIFO).cont.<br />
procedure procesolector;<br />
{ while (true) {comenzarleer; leerdatos; fin leer;}<br />
procedure procesoescritor;<br />
{ while (true) { comenzarescribir; escribirdatos; finescribir }<br />
{cobegin<br />
procesolector; procesolector; ...<br />
procesoescritor; procesoescritor; ...<br />
coend; }
2. Sincronización en Monitores<br />
2.4.3. Implementación con semáforos <strong>de</strong>l productor/consumidor<br />
• Propuesta <strong>de</strong> Brinch Hansen(/*signal es la última instrucción*/<br />
program productorconsumidor;<br />
CONST tamaño=...;<br />
VAR b: array [0..tamaño-1] of integer; in, out, n: integer;<br />
s: semaphore; /para E.M.*/<br />
semnovacio, semnolleno: semaphore; /* binarios */<br />
contnovacio, contnolleno: integer;<br />
procedure añadir (v:integer);<br />
{ P(s); if (n==tamaño) { contnovacio+ +; V(s); P(semnovacio); contnovacio --}<br />
b[in] = v; in := (in + 1) % tamaño; n + +;<br />
if contnolleno>0 V(semnolleno) else V(s);}<br />
procedure tomar(var v:integer);<br />
{ P(s); if (n==0) {contnolleno + +; V(s); P(semnolleno); contnolleno - -}<br />
v := b[out]; out := (out + 1) % tamaño; n := -- ;<br />
if contnovacio>0 V(semnovacio) else V(s); }
2. Sincronización en Monitores<br />
2.4.3. Implementación con semáforos <strong>de</strong>l productor/consumidor<br />
procedure productor;<br />
var v: integer;<br />
{while (true) {producir(v); añadir(v)}<br />
procedure consumidor;<br />
var v:integer;<br />
{while (true) {tomar(v); consumir(v)}<br />
{in =out=n = 0; s = 1;<br />
contnolleno = semnolleno = 0;<br />
contnovacio = semnovacio = 0;<br />
cobegin<br />
productor;<br />
consumidor;<br />
coend;}