• No se han encontrado resultados

Clase 6 Monitores.pptx

N/A
N/A
Protected

Academic year: 2020

Share "Clase 6 Monitores.pptx"

Copied!
66
0
0

Texto completo

(1)

Monitores

(2)

Definición

Un monitor es un mecanismo de software para

control de concurrencia que contiene los datos

y los procedimientos necesarios para realizar

la asignación de un determinado recurso o

grupo de recursos compartidos reutilizables

en serie.

La Noción de un monitor fue presentada

(3)

Uso de los Monitores

Un monitor se usa para manejar todas las

funciones de concurrencia, comunicación

entre procesos y localización física de

recursos en una región crítica.

Para llevar a cabo la asignación de un recurso

(4)

Los datos contenidos en el monitor pueden

ser

globales

(accesibles a

todos

los

procedimientos dentro del monitor), o locales

(accesibles a un procedimiento específico).

Estos datos sólo son accesibles dentro del

(5)

Estructura del Monitor

El monitor consta de varios procedimientos

que manipulan datos internos y existe una

parte de inicialización.

El código del monitor consta

de 2 partes lógicas:

• El algoritmo para la

manipulación del recurso.

(6)

Postergación Indefinida.

Para asegurar que un proceso obtenga el

(7)

Variables de Condición

Dado que un proceso puede necesitar esperar

fuera del monitor por varias razones se creo un

mecanismo llamado variable de condición.

Una variable de condición se controla con solo

dos operaciones:

wait(variable) Forma el proceso en la lista de espera

de la variable de condición.

signal(variable) Libera al primer proceso de la lista de

lala variable de decisión. Esta operación implica la

salida del proceso actual del monitor.

Normalmente se usa una variable de condición

(8)

Variables de Condición

Si el proceso que se encuentra dentro del

monitor encuentra que el recurso que ocupa no

está disponible, el procedimiento del monitor

debe sacar momentáneamente al proceso y

hacerlo esperar fuera del monitor (wait).

El proceso NO puede permanecer en el monitor

ya que esto viola la condición de exclusión

mutua y debe esperar fuera del monitor la

liberación del recurso que necesita.

(9)

En el estado activo existen tres opciones para que un proceso abandone el monitor:

1. SALIR (exit): en este caso un proceso llega al final del procedimiento de monitor que está ejecutando. Por ejemplo, en la salida normal de una región crítica .

2. CONTINUAR (continue): Esta operación se realiza cuando el proceso activo completó una acción que otro proceso pudiera estar esperando (en el estado bloqueado) y entonces le envía la señal (signal) de que puede continuar. Al proceso bloqueado se le permite regresar a activo. Si no hay procesos bloqueados se abre la entrada del monitor.

3. RETARDAR (delay): El retardo se presenta cuando un proceso necesita el resultado de una acción que otro proceso aún no realiza y entonces espera (wait).

El proceso que desbloquea a otro a través de la operación continuar

debe dejar el monitor

(10)

Problema de los Lectores y Escritores

 La solución de este problema se puede usar como un modelo para implementar un mecanismo de acceso a información compartida.

 Problema: Existen varios procesos lectores y escritores que acceden una base de datos común, las reglas de acceso son:

1. Cualquier número de procesos lectores puede acceder la base de datos en forma concurrente.

2. Cuando un proceso escritor está accediendo la base de datos ningún otro proceso, ni lector, ni escritor podrá accederla.

3. Cuando están accediendo procesos lectores y se tenga por lo menos a un escritor esperando acceso, los lectores que llegaron después del escritor no acceden directamente sino esperan.

4. Los procesos lectores esperando que un escritor termine su acceso tienen prioridad sobre el siguiente escritor.

(11)

Problema de los Filósofos

Existen n filósofos que pasan su vida pensando y comiendo.

Cada filósofo tiene su lugar en una mesa circular en cuyo

centro está un plato con espagueti.

Para comer espagueti se requieren dos Tenedores, pero sólo

hay n tenedores, uno entre cada par de filósofos.

Los únicos tenedores que puede tomar un filósofo son los

inmediatos a su izquierda y derecha.

El problema es simular el comportamiento de un filósofo

igual para todos, de tal forma que:

Se

evite

el

interbloqueo,

por

ejemplo,

cuando

simultáneamente cada filósofo toma su tenedor izquierdo y

se queda esperando por su tenedor derecho.

Se evite la inanición esto es, que un filósofo no pueda

(12)

Monitores en Java

Un monitor es un objeto que implementa el

acceso en exclusión mutua a sus métodos.

En Java se aplica a los métodos de la clase

(13)

Monitores en Java

Disciplinas de señalización de monitores son:

Signal and exit : Después de hacer notify el

thread debe salir del monitor y el thread que

recibe la señal de que es el siguiente en entrar en

el monitor.

Signal and continue: El thread que recibe la señal

no tiene que ser necesariamente el siguiente en

entrar en el monitor.

Java trabaja el modelo de Signal y Continue, lo

(14)

Monitores en Java

Todos los objetos tienen un bloqueo asociado,

lock o cerrojo, que puede ser adquirido y liberado

mediante el uso de métodos y sentencias

synchronized.

La sincronización obliga a que la ejecución de los

dos hilos sea mutuamente exclusiva en el tiempo.

Mecanismos de bloqueo:

Métodos synchronized (exclusión mutua).

Bloques synchronized (regiones críticas).

Mecanismos de comunicación de los threads

(variables de condición):

(15)

Código Sincronizado en Java

Java soporta la exclusión mutua mediante la

palabra reservada synchronized que puede

aplicarse a un método completo, o a una

secuencia de instrucciones.

Sincronización del método

class Monitor {

private int valor= 0 ;

public synchronized void suma ( ) {

valor++; }

(16)

En Java hay una cerradura (lock) por objeto.

Cuando un thread llama a un método

sincronizado, espera hasta obtener el acceso

exclusivo

al objeto

que lo contiene.

Una vez que se ha ejecutado el método, se libera

el cerrojo.

Sincronización del objeto

class Monitor {

private int valor= 0 ; public void suma ( ) {

Synchronized (this) { valor++;}

(17)

Condiciones de sincronización

Cuando una hebra que tiene el lock

de un objeto y debe suspenderse

debido a alguna condición de

sincronización, se introduce en el

conjunto de espera del objeto,

llamando al método:

void wait()

Cuando una hebra ejecuta wait():

(18)

Ejemplo Productor-Consumidor

El productor genera un entero entre 0 y 9, lo

almacena en un objeto Monitor_Almacen, e

imprime el número generado, el productor

duerme durante un tiempo aleatorio entre 0 y

100 milisegundos antes de repetir el ciclo de

generación de números.

El

consumidor,

por

su

parte,

está

(19)

Clase Monitor_Almacen

class Monitor_Almacen {

private int numero;

private boolean disponible = false;

public synchronized int get() { while (disponible == false) { try {

wait();

} catch (InterruptedException e) { }

}

disponible = false; notify();

return numero; }

public synchronized void put(int valor {

while (disponible == true) { try {

wait();

} catch (InterruptedException e) {

} }

numero = valor; disponible = true; notify();

(20)

Clase Productor

class Productor extends Thread { private Monitor_Almacen monitor1; private int num;

public Productor(Monitor_Almacen m, int num1) {

monitor1 = m; this.num = num1; }

public void run() {

for (int i = 0; i < 10; i++) { monitor.put(i);

System.out.println("Productor #"+this.num+" pone: " +i); try {

sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { }

(21)

Consumidor

class Consumidor extends Thread { private Monitor_Almacen monitor1 ; private int num;

public Consumidor(Monitor_Almacen m, int num1) {

monitor1 = m; this.num = num1; }

public void run() { int valor = 0;

for (int i = 0; i < 10; i++) {

valor = monitor1.get();

System.out.println("Consumidor #"+this.num+" obtiene:"+valor); }

(22)

Implementar Clase Principal

public static void main(String args[ ] )

{

Monitor_Almacen m = Monitor_Almacen( );

new Productor (m);

new Consumidor(m);

}

(23)

Ejemplo 2

Elroblema productor/consumidor2 con java.

Se compone de cuatro clases simples:

Cola_Monitor,cuyo acceso se trata de sincronizar a

sus métodos, es el monitor.

Productor, es un hilo que genera datos para la cola

Consumidor, es un hilo que consume datos de la

cola.

ProCon, crea una Cola_Monitor, Productor y

(24)

class Cola_Monitor

{

int n;

boolean valueSet = false; synchronized int get( ) {

if (!valueSet) try wait( );

catch(InterruptedException e);

System.out.println (“Obtenido: “ + n); valueSet = false;

notify( ); return n; }

}

synchronized int put(int n) {

if (valueSet) try wait( );

catch(InterruptedException e);

this.n = n;

valueSet = true; System.out.println (“Colocado: “ + n); notify( );

(25)

class Producer implements Runnable {

Q q;

Producer (Q q) {

this.q = q;

new Thread(this, “Producer”).start( ); }

public void run( ) {

int i = 0; while(true)

{ q.put( i++ ); } }

}

class Consumer implements Runnable

{ Q q;

Producer (Q q) {

this.q = q;

new Thread(this, “Consumer”).start( ); }

public void run( ) {

while(true) { q.get( ); } }

(26)

class ProCon

{

public static void main(String args[ ] )

{

Cola_Monitor q = new Cola_Monitor( );

new Productor (q);

(27)

Actividad Individual

Elabora el programa de Hola Mundo usando

monitores, donde Hilo 0 imprima «hola» y el

hilo1 imprima «mundo».

¿Cuál es la diferencia entre el programa de

Hola_ Mundo con semáforos y Hola_Mundo

con monitores?

¿Cuál de los dos mecanismos se te facilito

implementar’

Realiza el reporte incluyendo los dos

(28)

class Monitor_HolaM

{

private String cad;

private boolean disponible = true;

public Monitor_HolaM(){ cad=null;

}

public synchronized void imprime1(String cad) {

while (disponible == false) {

try {

wait();

} catch (Exception e){} }

System.out.println("Nombre: "+ Thread.currentThread().getName()+ cad);

disponible = false; notify();

}

public synchronized void

imprime2(String cad) {

while (disponible == true) {

try {

wait();

(29)

class P1 implements Runnable{ Monitor_HolaM m; String name; public P1(String name,Monitor_HolaM m){ this.m = m;

this.name=name; }

public void run(){ for(int i=0;i<3;i++) { m.imprime1(" Hola "); } } }

class P2 implements Runnable{ Monitor_HolaM m;

String name;

public P2(String

name,Monitor_HolaM m){ this.m = m;

this.name=name; }

public void run(){

for(int i=0;i<3;i++) {

m.imprime2(" Mundo ");

(30)

Clase Principal

public class HolaM {

public static void main(String[] args) {

Monitor_HolaM m = new Monitor_HolaM(); P1 p1= new P1("hilo1: ",m);

P2 p2= new P2("hilo2: ",m); Thread a = new Thread(p1); Thread b = new Thread(p2); a.start();

b.start();

(31)

Ejemplo 3 Problema de los Jardines

Existen en N hilos que compiten por entrar por

una puerta para incrementar un valor

(32)

Exclusión Mutua

class Cont {

private int c = 0;

public synchronized void inc(int i){ c++;

System.out.println("Nombre: " + Thread.currentThread().getName() +" " + c);

}

public synchronized int valor(){

return c; }

}

class puerta implements Runnable{ Cont c;

public puerta(Cont c){this.c = c;} public void run(){

for (int i = 0; i<20; i++) c.inc(1);

} }

public class UsaJardines {

public static void main(String[] args){ final int N = 10;

Cont c = new Cont();

puerta[] p = new puerta[N];

for (int i = 0; i< N; i++) p[i] = new puerta(c); Thread[] ph = new Thread[N];

for (int i = 0; i< N; i++) ph[i] = new Thread(p[i]);

for (int i = 0; i< N; i++) ph[i].start(); for (int i = 0; i< N; i++)

try{ph[i].join();

}catch (InterruptedException e){} System.out.println(c.valor()); }

(33)

Java no asigna ninguna estructura concreta a

las hebras que están en el conjunto de

entrada.

La implementación podría usar

Una FIFO

Una LIFO

(34)
(35)

Java: notify-and-continue

Java utiliza el mecanismo notify-and-continue,

es decir, el hilo que hace notify() continúa con

el lock del monitor. Por lo tanto, el hilo que

espera debe ejecutar un código del tipo:

while (!condicion)

try {wait();

(36)

Java y Variables de Condición

En Java podemos pensar que hay una

condición(declarada de manera implícita) por

cada objeto sincronizado.

Por lo cual debemos declarar los recursos

compartidos como objetos que tendrán

asociado una variable de condición para

verificar su estado.

Las variables tipos C

ondition

que solo

(37)

Variables tipos Condition

Valores

: No toma ningún tipo de valor, pero

tiene asociada una lista de procesos

suspendidos

Operaciones:

Delay , suspende el proceso que lo ejecuta y lo

incluye en la lista de una variable Condition.

Resume, Reactiva un proceso de la lista asociada

a una variable Condition.

empty , retorna True si la lista de procesos de la

(38)

Productor/Consumidor con condiciones y

bloqueo

public class Condition {

public Condition() {

}

public synchronized void delay(){

try{wait(); // suspende al hilo que lo ejecuta }catch (Exception e){};

}

public synchronized void resume(){

try{notify(); // despierta un hilo suspendido }catch (Exception e){};

}

(39)

public class BufferCond {

private int[] b; private int tam; private int i=0; private int j=0;

private int numDatos = 0;

private final Condition nolleno = new Condition();

private final Condition novacio = new Condition();

public BufferCond(int t) {

tam = t;

(40)

public synchronized void poner(int d) throws InterruptedException

{

while (numDatos == tam) nolleno.delay();

b[i] = d;

i = (i + 1); //% tam; numDatos++;

novacio.resume(); }

public synchronized int extraer() throws InterruptedException {

while (numDatos == 0) novacio.delay();

int aux = j;

(41)

public class ProductorCon implements Runnable{ Buffer2 b; int id; public ProductorCon(BufferCond b,int id){

this.b = b; this.id = id; }

public void run(){

System.out.println("comienza productor");

try {

b.poner(id);

} catch (Exception e){};

System.out.println("Productor: "+id +" puso: "+id);

}

}

public class ConsumidorCon implements Runnable

{

Buffer2 b; int id;

public

ConsumidorCon(BufferCond b, int id){ this.b = b;

this.id = id; }

public void run(){ int d = 0;

System.out.println("comienza consumidor " );

try{d = b.extraer();

} catch (Exception e){};

System.out.println("Consumidor: " + id+" extrajo " +d);

(42)

public class ProduConsCond {

public static void main(String[] args) {

BufferCond b = new BufferCond(10); for (int i = 0; i<10; i++)

{

ProductorCon pc = new ProductorCon(b,i); ConsumidorCon cc = new ConsumidorCon(b,i); //System.out.println("comienza el programa"); Thread ph = new Thread(pc);

Thread ch = new Thread(cc); ph.start();

ch.start();

} }

(43)

Múltiples productores y consumidores

Hay varios procesos productores y

consumidores.

Todos los procesos utilizan el buffer en

exclusión mutua.

Un productor no puede escribir hasta que no

hay sitio

en el buffer.

Los consumidores leen todos los datos

producidos

En el mismo orden. Si el buffer está vacío

esperan

1 2 3 4

C1 C2 C2

P 1

(44)

Locks

 En Java 5.0, se introdujo un mecanismo de sincronización alternativo

al lock intrínseco que se define a través de la clase ReentrantLock y cuya funcionalidad se define a través de la interfaz Lock.

El ReentrantLock se introduce por las limitaciones del lock intrínseco:

No es posible interrumpir un thread que espera un wait.

No es posible intentar de forma no bloqueante adquirir un lock sin

suspenderse definitivamente en él.

 Los lock intrínseco deben ser liberados en el mismo bloque de código

en el cual se suspendió.

 Comparación:

 El Lock intrínseco conduce a un estilo de programación sencillo,

seguro y compatible con la gestión de excepciones

El ReentrantLock conduce a estrategias menos seguras, pero mas

(45)

Interface java.util.concurrent.locks

public interface Lock{

//Provide more extensive locking operations than can be obtained using synchronized // methods and statements.

void lock();

// Acquires the lock

void lockInterruptibly() throws InterruptedExcetion;

// Acquires the lock unless the current thread is interrupted.

boolean tryLock();

// Acquires the lock only if it is free at the time of invocation.

boolean tryLock(long timeout,TimeUnit unit) throws InterruptedExcetion;

// Acquires the lock if it is free within the given waiting time and the current // thread has not been interrupted.

void unlock();

// Releases the lock.

Condition newCondition();

//Returns a new condiction instance that is bound to this Lock instance. }

La interfaz Lock define un conjunto de operaciones abstractas de toma y liberación

de un lock.

A diferencia del lock intrínseco, la interface Lock ofrece diferentes formas de toma

(46)

Objetos Condition

Cuando se utiliza un Lock explícito para definir

una región asíncrona, dentro de ella se

utilizan

los

objetos

Condition

como

mecanismo de sincronización entre threads.

Un objeto

Condition

está estructuralmente

ligado a un objeto Lock. Sólo puede crearse

invocando el método

newCondition()

sobre un

objeto Lock.

El objeto

Condition

solo puede ser invocado

(47)

Es ofrecida por variables de condición asociadas a un reentrantLock : public interface Condition {

void await();

//Causes the current thread to wait until it is signalled or interrupted. boolean await(long time, TimeUnit unit)

// Causes the current thread to wait until it is signalled or interrupted, or the specified

// waiting time elapses.

long awaitNanos (long nanosTimeout)

//Causes the current thread to wait until it is signalled or interrupted, or the specified

// waiting time elapses. void awaitUninterruptibly()

// Causes the current thread to wait until it is signalled. boolean awaitUntil(Date deadline)

// Causes the current thread to wait until it is signalled or interrupted, or the specified

// deadline elapses. void signal()

// Wakes up one waiting thread. void signalAll()

// Wakes up all waiting threads.

(48)

Locks

Los métodos/instrucciones synchronized modelan el acceso exclusivo a lock de un monitor implícito asociado a un objeto, típicamente un recurso compartido por varias hebras.

Sin embargo, cuando una hebra necesita usar más de un recurso, debe liberar los locks de los recursos en orden inverso a como se han obtenido, lo que en ocasiones puede no ser adecuado

....

A.acquire();

B.acquire();

C.acquire(); A.release();

(49)

Locks

public class ReentrantLock

ReentrantLock l = new ReentrantLock();

Un Lock para la exclusión mutua con la misma

(50)

Locks: el problema de los jardines

public class Cont {

Lock l = new ReentrantLock(); private int c = 0;

public void inc(int i){ l.lock();

try{ c++;

} finally {

l.unlock(); }

}

Implementación de la interfaz lock

Pido el lock

(51)

Locks: el problema de los jardines

public int valor(){ l.lock();

try{

return c; } finally {

l.unlock(); }

}

Pido el lock

Devuelvo el lock

(52)

Locks: condiciones

public interface Condition

Las condiciones clasifican los métodos del monitor (wait,

notify and notifyAll) en distintos objetos de forma que es

posible tener múltiples conjuntos de espera por objeto, asociados a locks.

Lock l = new ReentrantLock() Condition c1 = l.newCondition(); Condition c2 = l.newCondition();

Para modelar las condiciones de sincronización usamos la Interfaz Condition.

(53)

Locks: condiciones

Métodos

void await() throws InterruptedException

Suspende a la hebra en la condición correspondiente

void signal()

Despierta una de las hebras que espera. La hebra tiene que

conseguir el lock correspondiente antes de continuar su ejecución.

(disciplina signal-and-continue)

void signalAll()

Desperta a todas las hebras que esperan. Cada hebra tiene que conseguir el lock correspondiente antes de continuar su ejecución.

(54)

Locks: condiciones

Lock l = new ReentrantLock() Condition c1 = l.newCondition(); Condition c2 = l.newCondition();

l.lock(); try {

while (!condicion1)

c1.await(); // mientras !condicion1 espera en c1 // condicion1 se satisface

// cambia el estado del objeto y condicion2 es cierta c2.signal(); // despertar una hebra que espera

} finally {

(55)

Productor/Consumidor

package condicion;

import java.util.concurrent.locks.*; public class Buffer {

private int[] b; private int tam; private int i=0; private int j=0;

private int numDatos = 0;

private final ReentrantLock lockBuffer = new ReentrantLock();

private final Condition nolleno = lockBuffer.newCondition(); private final Condition novacio = lockBuffer.newCondition();

public Buffer(int t){ tam = t;

b = new int[tam]; }

(56)

Productor/Consumidor

public void poner(int d) throws InterruptedException{ System.out.println("productor quiere poner "+d); try{

lockBuffer.lock();

while (numDatos == tam) nolleno.await();

b[i] = d;

i = (i + 1) % tam; numDatos++; novacio.signal();

}finally{lockBuffer.unlock();} }

(57)

Productor/Consumidor

public int extraer() throws InterruptedException{

System.out.println("consumidor quiere extraer" + numDatos); try{

lockBuffer.lock();

while (numDatos == 0) novacio.await();

int aux = j;

j = (j + 1) % tam; numDatos--;

nolleno.signal(); return b[aux];

(58)

Barbero Dormilón

import java.util.concurrent.locks.*; public class Barberia {

private Lock BLock = new ReentrantLock();

private Condition cBlibre = BLock.newCondition();

private Condition cSillaOcupada = BLock.newCondition(); private Condition cPuertaAbierta = BLock.newCondition(); private Condition cSiguiente = BLock.newCondition();

private boolean Blibre = false;

(59)

Barbero Dormilón

public void siguiente(){ BLock.lock(); try{

System.out.println("Barbero libre"); Blibre = true;

cBlibre.signal();

while (!SillaOcupada)

try{cSillaOcupada.await();}

catch (InterruptedException e){}

}finally {

BLock.unlock(); }

(60)

Barbero Dormilón

public void finPelar(){ BLock.lock(); try{

PAbierta = true;

cPuertaAbierta.signal(); while (PAbierta)

try{cSiguiente.await();}

catch (InterruptedException e){};

}finally {

BLock.unlock(); }

(61)

Barbero Dormilón

public void qPelar(int i){ BLock.lock();

try{

while (!Blibre)

try{cBlibre.await();}

catch (InterruptedException e){}; Blibre = false;

SillaOcupada = true;

System.out.println("Cliente "+i+" se sienta en la silla"); cSillaOcupada.signal();

while (!PAbierta)

try{cPuertaAbierta.await();} catch (InterruptedException e){};

System.out.println("Cliente "+i+" se va"); PAbierta = false;

cSiguiente.signal(); }finally {

(62)

Barbero Dormilón

public void qPelar(int i){ BLock.lock();

try{

while (!Blibre)

try{cBlibre.await();}

catch (InterruptedException e){}; Blibre = false;

SillaOcupada = true;

System.out.println("Cliente "+i+" se sienta en la silla"); cSillaOcupada.signal();

while (!PAbierta)

try{cPuertaAbierta.await();} catch (InterruptedException e){};

System.out.println("Cliente "+i+" se va"); PAbierta = false;

cSiguiente.signal(); }finally {

(63)

Barbero Dormilón

public class Barbero implements Runnable { Barberia b;

public Barbero(Barberia b){ this.b = b;

}

public void run(){ while (true){

b.siguiente();

System.out.println("Barbero Pela Cliente"); // Barbero pela cliente

b.finPelar(); }

}

(64)

Barbero Dormilón

public class cliente implements Runnable{ Barberia b;

int id;

public cliente(Barberia b,int i){ this.b = b;

id = i; }

public void run(){ b.qPelar(id); }

(65)

Barbero Dormilón

public class UsaBarberia {

public static void main(String[] args){ final int N = 125;

Barberia b = new Barberia(); Barbero bar = new Barbero(b); cliente[] c = new cliente[N];

for (int i = 0; i<N; i++) c[i] = new cliente(b,i);

Thread bh = new Thread(bar); bh.start();

Thread[] ch = new Thread[N];

for (int i = 0; i<N; i++)

ch[i]= new Thread(c[i]);

for (int i = 0; i<N; i++) ch[i].start();

(66)

Investigar en Equipo

Cierres de exclusión mutua

java.util.concurrent.locks

• Interfaces Lock y Condition

– Lock permite gestionar los cierres de forma explícita • lock()

• unlock() • tryLock()

• newCondition()

Condition permite establecer más de una cola asociada a un cierre

• await()

• awaitUntil() • signal()

Referencias

Documento similar

¿Cómo se traduce la incorporación de ésta en la idea de museo?; ¿Es útil un museo si no puede concebirse como un proyecto cultural colectivo?; ¿Cómo puede ayudar el procomún

Asimismo una reflexión calmada sobre las intrincadas relaciones existentes en el péndulo que va del ODM 1 al ODM 8, debería conducirnos a observar por qué las formas mediante las

Y tú sabes cómo es de desubicado Bruno, saca esa pala- bra cada vez y Marcial y yo nos miramos como diciendo «qué se le va a hacer».. Pero yo creo que Marcial se va a componer,

Pero cuando vio a Mar sacar el fuego de bajo su ala, voló de vuelta a su tribu a contarles lo que había visto.... Justo antes de que el sol saliera, Tatkanna se despertó y comenzó

o esperar la resolución expresa&#34; (artículo 94 de la Ley de procedimiento administrativo). Luego si opta por esperar la resolución expresa, todo queda supeditado a que se

Busqué, tal como lo vienen intentando los artistas, no quedar atrapada en etiquetas que distingan estilos o categorías fijas – circo tradicional, nuevo, contemporáneo – sino más

El interesado podrá acudir ante el señor Personero Municipal o a la Defensoría del Pueblo para que se le colabore en la elaboración de su demanda o petición, así como en los

37 El TPI, en los fundamentos jurídicos del 149 al 154 de la sentencia «Virgia- micina», examinó las dos actividades complementarias que integran la evaluación de riesgos: