UNIVERSIDAD NACIONAL DE SAN AGUSTIN
Curso: Sistemas Operativos El problema del lector - escritor usado sem!"oros #ro"esor: Freddy Orlando Gonzales Saji
Alumos: •
Diego Ranilla Gallegos
•
Ruben Huanca Morales
•
Vidal Soncco Merma
2015 El problema del lector escritor Usando semáforos
Un semáforo sirve para controlar el número de hilos que acceden a la variable compartida, en este caso el libro. Si inicializamos el semáforo a 1 se comportará como un semáforo binario, aunque también lo podemos inicializar por ejemplo a 15, para estionar adecuadamente los permisos que le queramos otorar. Un semáforo puede ser liberado por otro proceso, en los loc!s deben ser liberados por el mismo proceso.
Características:
"ara el lector# Si ha$ escritores activos o en espera, este lector tiene que esperar %los escritores • tienen prioridad&. 'e otra manera, este lector puede leer %posiblemente con otros lectores& • (uando el último lector termina, si ha$ escritores esperando, este último lector • debe llamar a uno de ellos. "ara el escritor# Si ha$ lectores o escritores activos, este escritor tiene que esperar %cada uno • tiene que terminar antes que el escritor pueda actualizar la base de datos&. 'e otra manera, este escritor puede escribir %$ tiene e)clusivo acceso a la base • de datos&. (uando el escritor termina# • 1. Si ha$ escritores esperando, debe llamar uno %escritores tienen prioridad&. *. Si ha$ solamente lectores esperando, debe llamar uno. Interfaz#
Código: Lector!a"a
+a clase lector se encarará de leer el libro, varios lectores pueden el mismo libro simultáneamente. l método run se ejecutará mientras que el libro no esté terminado. +a funcionalidad es la que se pide en el enunciado, con cada acci-n llamamos a estion.parar por si hemos pulsado el bot-n de pausa. pac#age semaforos$ p%blic class Lector e&tends '(read ) pri"ate int identLector$ pri"ate Libro libro$ pri"ate *estion gestion$ p%blic Lector+int identLector, Libro libro, *estion gestion- ) t(isidentLector . identLector$ t(islibro . libro$ t(isgestion . gestion$ / pri"ate "oid Esperar+int min, int ma&- ) tr ) sleep%min %int& %ma) / 0ath.random%&&& / catc( +E&ception e- ) / / "erride p%blic "oid r%n+- )
3(ile +libro.libro2erminado%& 33 false- ) estion.parar%& sperar%1444, 1444& estion.parar%& libro.leer+ibro%ident+ector& estion.parar%& sperar%544, 1444& estion.parar%& libro.terminar+eer%ident+ector& /
/ /
Escritor!a"a
+a clase escritor s-lo podrá escribir el libro de 1 en 1 $a que estamos en una rei-n crtica con variables compartidas tal $ como pone el enunciado. pac#age semaforos$ p%blic class Escritor e&tends '(read ) pri"ate int identEscritor$ pri"ate Libro libro$ pri"ate *estion gestion$ p%blic Escritor+int identEscritor, Libro libro, *estion gestion- ) t(isidentEscritor . identEscritor$ t(islibro . libro$ t(isgestion . gestion$ / pri"ate "oid Esperar+int min, int ma&- ) tr ) sleep%min %int& %ma) / 0ath.random%&&& / catc( +E&ception e- ) / / "erride p%blic "oid r%n+- ) for +int i . 0$ i 4 5$ i- ) estion.parar%& sperar%1444, 1444& estion.parar%& libro.escribir+ibro%identscritor& estion.parar%& sperar%144, 4& libro.terminarscribir%identscritor& / / /
Libro!a"a
sta clase libro es la variable compartida $ por tanto, la que tenemos que proteer de lectores6escritores para que el prorama funcione satisfactoriamente.
(reamos todos los atributos necesarios para que el prorama funcione, inclu$endo los loc!s para estionar la entrada $ salida de los escritores. pac#age semaforos$ import !a"a%tilconc%rrent6emap(ore$ import !a"a%tilloggingLe"el$ import !a"a%tilloggingLogger$ p%blic class Libro ) pri"ate 6tring libro$ pri"ate Interfaz interfaz$ pri"ate int lect%ras$ pri"ate 6emap(ore semaforo7$ p%blic Libro+Interfaz interfaz, 6emap(ore semaforo- ) t(isinterfaz . interfaz$ libro . 88$ lect%ras . 0$ semaforo7 . semaforo$ / p%blic "oid leerLibro+int identificador- ) tr ) semaforo7.acquire%& / catc( +Interr%ptedE&ception e&- ) +oer.et+oer%+ibro.class.et8ame%&&.lo%+evel.S9:, null, e)& /
interfazmeter9atos+1, interfazleer9atos+1- 88 identificador 8 8-$ lecturas
/
p%blic boolean libro'erminado+- ) if +librolengt(+- .. 50- ) return true / else ) return false / / p%blic "oid terminarLeer+int identificador- ) interfazmeter9atos+1, interfazleer9atos+1-replace7ll+88 identificador 8 8, 88--$ if +libro'erminado+-- ) interfaz.meter'atos%;, interfaz.leer'atos%;& <+eido por < identificador <# < libro <=n<& / semaforo7.release%& / p%blic "oid escribirLibro+int identificador- ) tr ) semaforo7.acquire%15& / catc( +Interr%ptedE&ception e&- ) +oer.et+oer%+ibro.class.et8ame%&&.lo%+evel.S9:, null, e)& /
libro 3 libro identificador interfaz.meter'atos%*, interfaz.leer'atos%*& identificador& interfaz.meter'atos%>, libro&
/ p%blic "oid terminarEscribir+int identificador- ) interfaz.meter'atos%*, interfaz.leer'atos%*&.replace7ll%<< identificador, <<&& semaforo7.release%15& / /
*estion!a"a
sta clase es la que estiona los botones de reanudar $ parar. Si pulsamos el bot-n reanudar pondremos pausar a falso $ el prorama, liberamos el semáforo. Si pulsamos el bot-n detener, pondremos pausar a true $ activaremos el semáforo. 7nalizamos la condicion de pausar. Si es true activamos el semáforo $ continuaci-n lo liberamos. pac#age semaforos$ import !a"a%tilconc%rrent6emap(ore$ import !a"a%tilloggingLe"el$ import !a"a%tilloggingLogger$ p%blic class *estion ) pri"ate 6emap(ore semaforo$ p%blic boolean pa%sar$ p%blic *estion+- ) semaforo 3 ne? Semaphore%1, true& / p%blic "oid rean%dar+- ) pausar 3 false semaforo.release%& / p%blic "oid detener+- ) tr ) semaforo.acquire%& pa%sar . tr%e$ / catc( +Interr%ptedE&ception e&- ) +oer.et+oer%@estion.class.et8ame%&&.lo%+evel.S9:, null, e)& / / p%blic "oid parar+- ) if +pa%sar- ) tr ) semaforo.acquire%& / catc( +Interr%ptedE&ception e&- ) +oer.et+oer%@estion.class.et8ame%&&.lo%+evel.S9:, null, e)& / semafororelease+-$ / / /
Interfaz!a"a
"rorama principal $ el que ejecuta todos los hilos concurrentemente. (reamos un nuevo objeto @estion para reanudar $ parar el sistema. n el bot-n de reanudar, procedemos a habilitar el bot-n detener $ a deshabilitar el bot-n reanudar %que $a ha sido pulsado&. 7 continuaci-n, reanudamos el sistema llamando a <esti-n<. n el bot-n de detener, procedemos a habilitar el bot-n reanudar $ a deshabilitar el bot-n detener %que $a ha sido pulsado&. 7 continuaci-n, detenemos el sistema llamando a <esti-n<. +a clase meter'atos introduce los datos en el j2e)tAield, recibimos un número de otra clase para saber d-nde debemos introducir la informaci-n. @racias al s?itch podremos introducir fácilmente los datos en el j2e)tAield correcto. 7l ser void, no devuelve nada. +a clase leer'atos devuelve un Strin con el contenido del j2e)tAield. 'ependiendo del número pasado por parámetro leeremos un j2e)tAield u otro. Si no se corresponde con ninuno, devolvemos cadena vaca. pac$a%e sema"oros& import 'a(a)util)cocurret)Semap*ore& public class Iter"a+ e,teds 'a(a,)si%)./rame 0 public Iter"a+12 0 iitCompoets12& 3 public Gestio %estio 4 e Gestio12& 5Suppress6ari%s17uc*ec$ed72 88 9editor-"old de"aultstate47collapsed7 desc47Geerated Code7 pri(ate (oid iitCompoets12 0 388 98editor-"old pri(ate (oid reaudarActio#er"ormed1'a(a)at)e(et)ActioE(et e(t2 0 deteer)setEabled1true2& reaudar)setEabled1"alse2& %estio)reaudar12&
3
pri(ate (oid deteerActio#er"ormed1'a(a)at)e(et)ActioE(et e(t2 0 reaudar)setEabled1true2& deteer)setEabled1"alse2& %estio)deteer12& 3
pri(ate (oid 'Te,t/ield;Actio#er"ormed1'a(a)at)e(et)ActioE(et e(t2 0 88 TODO add
public static (oid mai1Stri% ar%s=>2 0 'a(a)at)E(et?ueue)i(o$eLater1e Ruable12 0 5O(erride
public (oid ru12 0 Iter"a+ iter"a+ 4 e Iter"a+12& iter"a+)setVisible1true2& iter"a+)reaudar)setEabled1"alse2& Semap*ore sema"oro 4 e Semap*ore 1@B true2&
Libro libro 4 e Libro1iter"a+B sema"oro 2& "or 1it i 4 ;& i 9 & i2 0 Lector l@ 4 e Lector1iB libroB iter"a+)%estio2& l@)start12& 3 "or 1it i 4 & i 9 @& i2 0 Escritor e@ 4 e Escritor1iB libroB iter"a+)%estio2& e@)start12& 3
3 32& 3
3
public (oid meterDatos1it iB Stri% datos2 0 sitc* 1i2 0 case @: 0 'Te,t/ield@)setTe,t1datos2& brea$& 3 case ;: 0 'Te,t/ield;)setTe,t1datos2& brea$& 3 case : 0 'Te,t/ield)setTe,t1datos2& brea$& 3 case F: 0 'Te,tArea@)setTe,t1datos2& brea$& 3 3 3 public Stri% leerDatos1it i2 0 sitc* 1i2 0 case @: retur 'Te,t/ield@)%etTe,t12& case ;: retur 'Te,t/ield;)%etTe,t12& case : retur 'Te,t/ield)%etTe,t12& case F: retur 'Te,tArea@)%etTe,t12& de"ault: retur 77& 3 3
Si el libro ha lleado a 54 habremos terminado de leer $ devolvemos un valor booleano.