programación concurrente: mecanismos de sincronización de bajo nivel

11

Click here to load reader

Upload: juan-antonio-de-la-puente

Post on 27-Jun-2015

230 views

Category:

Software


0 download

DESCRIPTION

Semáforos, cerrojos y variables de condición

TRANSCRIPT

Page 1: Programación concurrente: mecanismos de sincronización de bajo nivel

dit UPM

Algunos  derechos  reservados.  Este  documento  se  distribuye  bajo  licencia  Crea9ve  Commons  Reconocimiento-­‐NoComercial-­‐Compar9rIgual  3.0  Unported.  hBp://crea9vecommons.org/licenses/by-­‐nc-­‐sa/3.0/deed.es  

Programación  concurrente  — Mecanismos  de  sincronización  de  bajo  nivelJuan  Antonio  de  la  Puente     <[email protected]>                          

20141009

Page 2: Programación concurrente: mecanismos de sincronización de bajo nivel

Programación  concurrente  —  Mecanismos  de  bajo  nivel ©  2014  Juan  A.  de  la  Puente

Referencias

•ScoB  Oaks  &  Henry  WongJava  Threads O'Reilly  Media;  3rd  ed  (2004)    !

•Kathy  Sierra  &  Bert  Bates Head  First  Java,  ch.  15O'Reilly  Media;  2nd  ed  (2005)

2

Page 3: Programación concurrente: mecanismos de sincronización de bajo nivel

Programación  concurrente  —  Mecanismos  de  bajo  nivel ©  2014  Juan  A.  de  la  Puente

Mecanismos  de  sincronización  de  bajo  nivel

• Con  monitores  se  pueden  construir  programas  concurrentes  correctos  para  todo  9po  de  situaciones  

• A  veces  se  usan  otros  mecanismos  de  sincronización  de  menor  nivel  de  abstracción  -­‐ por  razones  de  costumbre    o  de  eficiencia  

‣ semáforos  ‣ cerrojos  explícitos  ‣ variables  de  condición  

• Son  digciles  de  usar  correctamente  y  pueden  dar  lugar  a  problemas  complicados

3

Page 4: Programación concurrente: mecanismos de sincronización de bajo nivel

Programación  concurrente  —  Mecanismos  de  bajo  nivel ©  2014  Juan  A.  de  la  Puente

Semáforos

• Un  semáforo  es  un  objeto  que  9ene  un  valor  entero  no  nega9vo  

• Su  valor  sólo  se  puede  alterar  mediante  dos  operaciones  atómicas  ‣ adquirir:  decrementa  el  valor  del  semáforo  -­‐ si  es  0,  la  hebra  que  lo  invoca  se  suspende  

‣ liberar:  incrementa  el  valor  del  semáforo  -­‐ si  hay  hebras  esperando,  con9núa  una  de  ellas  ✓ el  valor  del  semáforo  no  se  modifica  

• Es  un  mecanismo  elemental  de  sincronización  ‣ interés  histórico:  inventado  por  Edsger  Dijkstra  hacia  1965  

4

Page 5: Programación concurrente: mecanismos de sincronización de bajo nivel

©  2014  Juan  A.  de  la  PuenteProgramación  concurrente  —  Mecanismos  de  bajo  nivel

java.u2l.concurrent.Semaphore

public class Semaphore … { !/* constructor */ public Semaphore(int permits); /* adquirir */ public void acquire() throws InterruptedException; !/* liberar */ public void release(); … }

5

Page 6: Programación concurrente: mecanismos de sincronización de bajo nivel

©  2014  Juan  A.  de  la  PuenteProgramación  concurrente  —  Mecanismos  de  bajo  nivel

Exclusión  mutua  con  semáforosSemaphore mutex = new Semaphore(1); !// thread 1 // thread 2 … mutex.acquire(); mutex.acquire(); // región crítica // región crítica mutex.release(); mutex.release(); …

6

• El  valor  inicial  indica  que  se  dispone  de  1  permiso  para  acceder  a  un  recurso  (por  ejemplo,  variable  compar9da)  

• No  pude  haber  más  de  una  hebra  en  su  región  crí9ca

Page 7: Programación concurrente: mecanismos de sincronización de bajo nivel

©  2014  Juan  A.  de  la  PuenteProgramación  concurrente  —  Mecanismos  de  bajo  nivel

Productor-­‐consumidor  con  semáforospublic class Buffer<E> { ! private E almacen; Semaphore mutex = new Semaphore(1); // exclusión mutua Semaphore sitio = new Semaphore(1); // sitio para 1 dato Semaphore datos = new Semaphore(0); // no hay datos en buffer ! public void enviar(E dato) throws InterruptedException { sitio.acquire(); // espera que haya sitio mutex.acquire(); // acceso exclusivo al almacén almacen = dato; mutex.release(); // libera acceso exclusivo datos.release(); // avisa de que hay datos disponibles } ! public E recibir() throws InterruptedException { E dato = null; datos.acquire(); // espera que haya datos mutex.acquire(); // acceso exclusivo al almacén dato = almacen; mutex.release(); // libera acceso exclusivo sitio.release(); // avisa de que hay sitio return dato; } }

7

Page 8: Programación concurrente: mecanismos de sincronización de bajo nivel

©  2014  Juan  A.  de  la  PuenteProgramación  concurrente  —  Mecanismos  de  bajo  nivel

Comentarios

•Más  complicado  de  usar  y  entender  

• Es  fácil  cometer  errores.    ‣ acquire()  sin  release();  ‣ orden  incorrecto  ‣muchos  errores,  digciles  de  detectar  

• En  general,  es  mejor  usar  métodos  sincronizados

8

public void enviar(E dato) … { mutex.acquire(); sitio.acquire(); almacen = dato; datos.release(); mutex.release();

} !public E recibir() ... { … mutex.acquire(); datos.acquire(); dato = almacen; sitio.release(); mutex.release(); ...

}

Ejemplo

¿por  qué  es  incorrecto?

Page 9: Programación concurrente: mecanismos de sincronización de bajo nivel

Programación  concurrente  —  Mecanismos  de  bajo  nivel ©  2014  Juan  A.  de  la  Puente

Cerrojos  explícitos

• Como  los  que  se  usan  de  forma  implícita  en  synchronized  ‣ y  otras  formas  con  propiedades  algo  diferentes  

• Se  definen  en  java.u2ls.concurrent.locks  !

!

!

!

• Varias  implementaciones  ‣ ReentrantLock,  etc.

9

public interface Lock { void lock(); // bloquea el cerrojo void unlock(); // desbloquea la RC ... }

Page 10: Programación concurrente: mecanismos de sincronización de bajo nivel

Programación  concurrente  —  Mecanismos  de  bajo  nivel ©  2014  Juan  A.  de  la  Puente

Condiciones

• Permiten  la  sincronización  mediante  condiciones  explícitas  

• Se  definen  en    !

!

!

!

• Varias  implementaciones  en  java.u2l.concurrent.locks  • Digcil  de  usar,  mejor  usar  notify()  y  notifyAll()

10

public interface Condition { void await() // libera cerrojo y espera throws InterruptedException; void signal(); // desbloquea un thread void signalAll(); // desbloquea todos }

Page 11: Programación concurrente: mecanismos de sincronización de bajo nivel

Programación  concurrente  —  Mecanismos  de  bajo  nivel ©  2014  Juan  A.  de  la  Puente

Resumen

• A  veces  se  usan  mecanismos  de  sincronización  con  un  nivel  de  abstracción  menor  que  los  monitores  ‣ semáforos  ‣ cerrojos  ‣ variables  de  condición  !

• Razones  históricas  o  código  heredado  ‣ todo  se  puede  hacer  con  monitores  ‣mayor  nivel  de  abstracción,  menos  errores

11