programación concurrente — datos compar9dos y exclusión mutua · 2015. 11. 16. · exclusión...

Post on 22-Sep-2020

9 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

ditUPM

Algunosderechosreservados.EstedocumentosedistribuyebajolicenciaCrea9veCommonsReconocimiento-NoComercial-Compar9rIgual3.0Unported.hBp://crea9vecommons.org/licenses/by-nc-sa/3.0/deed.es

Programaciónconcurrente— Datoscompar9dosy exclusiónmutuaJuanAntoniodelaPuente <jpuente@dit.upm.es>

20151026

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Referencias

•ScoBOaks&HenryWongJavaThreads O'ReillyMedia;3rded(2004)

•KathySierra&BertBates HeadFirstJava,ch.15O'ReillyMedia;2nded(2005)

2

Datoscompar9dos

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Variablescompar9das

• Lashebrasdeunprogramapuedenserindependientes‣ laejecucióndeunahebranoafectaaloquehaganlasdemáshebras

• …peroamenudoesmásinteresantequevariashebrascooperenpararealizarunafuncióncomún

• Unmecanismodecooperaciónmuycorrienteconsisteenusarvariablescompar9das‣ variablesalasque9enenaccesovariashebras‣ lashebraspuedenconsultar(leer)elvalordelavariableenunmomentodeterminadoomodificarlo(escribir)

4

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Ejemplo

• Doshebrasqueincrementanconcurrentementeelvalordeuncontador

• Problema:elresultadodependedeenquéordenseentrelacelaejecucióndelasoperacionesdecadahebra‣ estosellamacondicióndecarrera

5

hebra1 hebra2

contador

contador++ contador++

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Operacionesatómicas

• Laoperacióncontador++noseejecutadeunasolavez‣ sedescomponeen

registro = contador // registro es una variable temporal local de cada thread

registro = registro + 1 // incrementar el valor del registro

contador = registro // actualizar el valor del contador

• Lasoperacionesquenosepuedendescomponersellamanatómicas‣ contador++noesatómica‣ perolasoperacionesenquesedescomponesíloson

✓ enrealidaddependedelaimplementación(JVMylenguajedemáquina)

• Cuandovariashebrasseejecutanconcurrentementeseentrelazalaejecucióndesusinstruccionesatómicas

• Veamosdossecuenciasdeejecuciónposibles‣ suponemosqueinicialmentecontador==0

6

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Secuenciasdeejecución(1)

7

registro=contador

hebra1

registro=registro+1

hebra2

registro=contador

registro=registro+1

contador=registro

contador=registro

registro ⟵ 0

registro ⟵ 1

registro ⟵ 0

registro ⟵ 1

contador ⟵ 1

contador ⟵ 1

contador == 0

contador == 1

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Secuenciasdeejecución(2)

8

registro=contador

hebra1

registro=registro+1

hebra2

registro=contador

registro=registro+1

contador=registro

contador=registro

registro ⟵ 0

registro ⟵ 1

registro ⟵ 1

registro ⟵ 2

contador ⟵ 2

contador ⟵ 1

contador == 0

contador == 2

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Condicióndecarrera

9

• ¡Elresultadopuedeser1o2!‣ dependedelasvelocidadesdeejecuciónrela9vasdelashebras- “quiéncorremás”

• Elresultadodeunprogramanodebedependerdeestosdetalles‣ imposibledepreverdeantemano‣ cadaejecuciónesdis9nta- comportamientoindeterminado

‣ imposiblehacerensayos- cadavezunresultadodiferente

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Ejemplo:variablecompar9da

public class PruebaCuenta {

static long cuenta = 0; /* variable compartida */

private static class Incrementa extends Thread { public void run () { for (int i = 0; i < 1000000; i++) { cuenta++; /* región crítica */ } } }

public static void main(String[] args) { new Incrementa().start(); /* hebra 1 */ new Incrementa().start(); /* hebra 2 */ System.out.println(“contador = “ + contador); } }

10

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Datoscompar9dosenobjetos

• Loscamposdedatosdeobjetosalosqueseaccededesdevariashebrastambiénsondatoscompar9dos‣ tambiénpuedendanlugaracondicionesdecarrera‣ daigualqueseaccedaalosdatosdirectamente(sisonvisibles)omediantemétodos

11

hebra1 hebra2

Contador

- cuenta

+ incrementar() + valor()

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Ejemplo:objetosconestado(1)

public class Contador { private long cuenta = 0; /* estado */ public Contador (long valorInicial) { cuenta = valorInicial; } public void incrementar () { cuenta++; /* modifica el estado */ } public long valor () { /* devuelve el valor */ return cuenta; } }

12

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Ejemplo:objetosconestado(2)

public class PruebaContador {

private static class Incrementa extends Thread { Contador contador;

public Incrementa (Contador c) { contador = c; }

public void run () { ... contador.incrementar(); /* región crítica */ ... } }

// continúa

13

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Ejemplo:objetosconestado(3)

// continuación

public static void main(String[] args) { Contador contador = new Contador(0); Thread hebra1 = new Incrementa(contador); Thread hebra2 = new Incrementa(contador); /* las dos hebras comparten el objeto contador */ hebra1.start(); hebra2.start(); ... }

14

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Regionescrí9casyexclusiónmutua

• Lossegmentosdecódigoenqueseaccedeavariablescompar9dassellamanregionescrí9cas

• Paraevitarcondicionesdecarreraesprecisoasegurarlaexclusiónmutuaentrelashebrasenlasregionescrí9cas

• Cuandounahebraestáenunaregióncrí9caningunaotrapuedeaccederalosmismosdatos‣ primerounahebraefectúatodaslasoperacionesdesuregióncrí9ca,luegolaotra‣ elordennoimporta,siemprequenoseentrelacenlasoperacioneselementales

• Deestaformaseconsiguequelasoperacionesconvariablescompar9dasseanatómicas

15

Cerrojos

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Cerrojos

• Uncerrojo(lock)esunmecanismodesincronizaciónparaasegurarlaexclusiónmutua

• Puedeestarenunodeestosdosestados:‣ bloqueado(cerrado)‣ desbloqueado(abierto)

• Dosoperacionesatómicas‣ bloquear(lock)- siyaestábloqueado,lahebrasequedaesperando

‣ desbloquear(unlock)- sihayhebrasesperando,con9núaunadeellas

• Paraasegurarlaexclusiónmutua‣ bloquearcerrojo//esperasiestáocupado‣ regióncrí9ca‣ desbloquearcerrojo//sialguienesperabapuedecon9nuar

17

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Ejemplo

18

registro=contador

hebra1

registro=registro+1

hebra2

registro=contador

registro=registro+1

contador=registro

contador=registro

registro ⟵ 0

registro ⟵ 1

registro ⟵ 1

registro ⟵ 2

contador ⟵ 2

contador ⟵ 1

contador == 0

contador == 2

bloquearcerrojocerrojo bloqueado

bloquearcerrojo

desbloquearcerrojo

desbloquearcerrojo

cerrojo desbloqueado

(cerrojo desbloqueado)

(cerrojo bloqueado)

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Problemasdeloscerrojos

• Esmuymecanismodemuybajonivelquenoesaconsejableu9lizardirectamente‣ hayquehacersiemprelock()yunlock(),eneseorden‣ puedesercomplicadoconestructurasdeprogramacomplejas‣ esfácilequivocarse,muchosproblemas

• Esmejordejarqueelcompiladorlohagapornosotros‣ integrarexclusiónmutuaconobjetos‣métodosybloquessincronizadosenJava

19

Monitores

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

ExclusiónmutuaenJava

21

• Javaproporcionamecanismosdesincronizaciónabstractos‣métodossincronizados‣ bloquessincronizados

• Definenpartesdelprogramaqueseejecutanenexclusiónmutua(regionescrí9cas)

• ElcompiladorylaJVMseencargandeges9onarloscerrojosdeformaimplícita

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Métodossincronizados

• Unmétodosincronizadoseejecutaenexclusiónmutuaconlosdemásmétodossincronizadosdelmismoobjeto

22

public class ContadorSincronizado {

private long cuenta = 0; /* estado */

public ContadorSincronizado (long valorInicial) { cuenta = valorInicial;

}

public synchronized void incrementar () {

cuenta++;

}

public synchronized long valor () { return cuenta;

}

}

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Métodossincronizados(con9nuación)

• Lasllamadasconcurrentesamétodossincronizadosseejecutanenexclusiónmutua

23

... public void run () { ... contador.incrementar(); /* región crítica */ ... } ...

• Cadaobjeto9eneasociadouncerrojo‣ Alempezaraejecutarunmétodosincronizadosebloqueaelcerrojo- siyaestababloqueado,lahebraqueinvocaelmétodosesuspende- lashebrasqueesperanestánenunalistaasociadaalobjeto(entryset)

‣ Alterminarsedesbloquea- sihayhebrasesperando,sereanudalaejecucióndeunadeellas

‣ Elcompiladorgeneraelcerrojoylosbloqueosydesbloqueos

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Implementación

24

lock

entryset

hebraen método

sincronizado

hebrasen espera

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Algunosdetalles

• Sóloseejecutanenexclusiónmutualosmétodossincronizados‣ siseolvidasincronizaralgúnmétodosepuedenproducircondicionesdecarrera

• Losmétodosdeclasetambiénsepuedensincronizar‣ seusauncerrojoparalaclaseyunoporcadaobjeto

• Losconstructoresnosepuedensincronizar‣ perosóloseinvocanalcrearunobjeto

25

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Monitores

• Unmonitoresunaclasequeencapsuladatoscompar9dosyoperacionesconlosmismos‣ todosloscamposdedatossehacenprivados- sólosepuedeaccederaellosatravésdemétodos

‣ todoslosmétodosestánsincronizados

• Esunesquemaclásicoparaconstruirprogramasconcurrentes‣ inventadoporPerBrinchHansenyC.AnthonyHoare(1974)

• Ventajas‣ lasincronizaciónseespecificaalmismo9empoquelosdatos‣ lashebrasqueaccedenalosdatosno9enenqueincluirningúnmecanismoespecial‣ consistenteconlosprincipiosdelaprogramaciónconobjetos

26

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Bloquessincronizados

• Permitendefinirregionescrí9casmutuamenteexclusivasconunagranularidadmenor

• Lasinstruccionesdelcuerposeejecutanenexclusiónmutua

• Seusaelcerrojoasociadoalobjeto• Puedeserú9lparamejorarlasprestaciones• Peroesmásdiwcildeusarquelosmétodossincronizados

27

synchronized(objeto) { instrucciones }

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Precauciones

• Hayqueiden9ficarbienlasregionescrí9cas‣ secuenciadeinstruccionesdondeseleeysemodificaelestadointernodelosobjetoscompar9dos‣ nosiempreesevidentedóndeestán‣ puedehaberregionescrí9casfueradelosdatosencapsuladossinosehandiseñadobienlosmétodos

• Hayquesincronizartodaslasregionescrí9cas‣ iden9ficarlasoperacionescondatoscompar9dosyrealizarlascomométodossincronizados

28

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Ejemplo(incorrecto)

29

public class Variable { private long valor = 0;

public Variable (long valorInicial) { valor = valorInicial; }

public synchronized void modificar(long v) { valor = v; }

public synchronized long valor() { return valor; } }

… Variable v = new Variable(0); … long x = v.valor(); // ¡La región crítica es x +=1; // todo esto!! v.modificar(x); // ¡No está sincronizada! ...

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Ejemplo(correcto)

30

public class Variable { private long valor = 0;

public synchronized void incrementar() { valor++; }

… }

… v.incrementar (); // Ahora está sincronizado …

Datosvolá9les

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Datosvolá9les

• Algunoscamposdedatossepuedendeclararvolatile ‣ indicaqueelvalorpuedecambiardesdeotrashebras‣ enmul9procesadoresnosehacencopiasprivadas‣ seaseguraquelaslecturasyescriturassonatómicas- ¡nadamás!

• Puedesereficientesiloúnicoquesehaceescambiarelvalorenunahebrayleerloenotra‣ porejemplo,parapararlaejecucióndeunahebra

32

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Ejemplo

public class Tarea extends Thread {

private volatile boolean vivo = true;

public void run() { while (vivo) { // actividad concurrente } }

public void para() { vivo = false; } }

33

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Precauciones

• Sólosonatómicaslalecturaylaescrituradedatosprimi9vos

volatile int i; … i++; // ¡no es atómico, puede haber carreras

• Sisedeclarancomovolá9lesarraysuobjetos,loselementosindividualesnoestánprotegidos

34

Ejemplo

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Ges9óndeunestacionamiento

• Variasentradasysalidas‣ sensoresqueavisancuandopasauncoche

• Supervisor‣muestralaocupacióndelestacionamiento(númerodecoches)

36

P

Entrada N

Entrada S Salida S

Sensor

Sensor Sensor

Supervisor

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Diseño

37

«monitor»Parking

- n : natural+ entra+ sale+ ocupado: natural

«thread»Sensor

- acceso, id

«thread»Supervisor

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Parking

public class Parking {

private int n = 0; // número de coches en el parking

// entra un coche por una de las puertas

public synchronized void entra (String puerta) {

n++;

}

// sale un coche por una de las puertas

public synchronized void sale (String puerta) {

n--;

}

// consulta

public synchronized int ocupado() {

return n;

}

}

38

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Sensor

public class Sensor extends Thread {

private String id; private Parking p; private Acceso acceso; // ENTRADA o SALIDA

public Sensor(Parking p, String id, Acceso acceso) { this.p = p; this.id = id; this.acceso = acceso; }

@Override public void run() { while (true) { … // detecta un coche switch (acceso) { case ENTRADA: p.entra(id); break; case SALIDA: p.sale(id); break; } } } }

39

©2014JuanA.delaPuenteProgramaciónconcurrente—Exclusiónmutua

Supervisor

public class Supervisor extends Thread {

private Parking p;

public Supervisor(Parking p) {

this.p = p;

}

@Override

public void run() {

// comprueba el estado del parking cada 10 s

while (true) {

System.out.println("Número de plazas ocupadas: " + p.ocupado());

try {

sleep(10*1000);

} catch (InterruptedException e) {

System.err.println(e.toString());

}

}

}

}

40

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Crí9ca

• Elmonitorprotegeelestadointernodelestacionamiento‣ nohaycarrerasalactualizaroleer

• Peronoseaseguraqueelestadoseacorrecto‣ nodeberíanentrarcochessielestacionamientoestálleno

• Hacefaltaunmecanismoquepermitaimponerestascondiciones‣ sincronizacióncondicional

41

Resumen

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Resumen

• Elaccesoconcurrenteavariablescompar9daspuededarlugararesultadoserróneos‣ carreras

• Laformadeevitaresteproblemaesasegurarlaexclusiónmutuaentrelaszonasdondeseusanesasvariables‣ regionescrí9cas

• Elmecanismobásicoparaconseguirlaexclusiónmutuaeselcerrojo‣ bloqueoydesbloqueoatómicos

• EnJavaseusanmétodosybloquessincronizados‣ usanuncerrojoasociadoimplícitamenteacadaobjeto

43

Programaciónconcurrente—Exclusiónmutua ©2014JuanA.delaPuente

Resumen(con9nuación)

• Losmonitoressonclasesqueaseguranunaccesocorrectoaobjetoscompar9dos‣ todosloscamposdedatossonprivados‣ todoslosmétodosestánsincronizados- exceptolosconstructores

• Unaclasequesepuedeusarsinproblemasdesdevariashebrassedicequeessegura(threadsafe)

44

top related