Sunteți pe pagina 1din 61
PR UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ
PR
UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ

PROGRAMAÇÃO PARALELA E DISTRIBUÍDA Fundamentos

Prof. Cesar Augusto Tacla

http://www.dainf.ct.utfpr.edu.br/~tacla

JAVAProgParSD/0030-ProgParalelaDistribuida.ppt

Sumário

1. Introdução

a. Definição de sistemas paralelos e distribuídos

b. Conceitos: programa, processo e thread

c. Criação de threads

d. Yield, Sleep, Join

e. Prioridade entre threads

f. Compartilhamento de memória

g. Máquina de estados de uma thread

2. Problemas de concorrência

a. Race condition

b. Vivacidade (deadlock, livelock, starvation)

c. Soluções (mutex, semáforos, monitor)

starvation) c. Soluções (mutex, semáforos, monitor) 22 Programação Paralela e Distribuída - Fundamentos/UTFPR
22
22

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

REFERÊNCIAS BIBLIOGRÁFICAS

(Coulouris et al., 2003) George Coulouris, Jean Dollimore, Tim Kindberg. Distributed Systems - Concepts and Design, Addison Wesley Publ. Comp., 3a edição, 2003.

(Tanenbaum & Steen, 2002) Andrew S. Tanenbaum, Maarten van Steen. Distributed Systems, Prentice-Hall International, 2002.

(Garg, 2004) Vijay K. Garg. Concurrent and Distributed Computing in Java, Wiley Inter-Science, 2004, 309p.

Concurrent programming in Java : design principles and patterns - 2nd ed / c2000 - Livros - Acervo 225079 LEA, Douglas. Concurrent programming in Java: design principles and patterns. 2nd ed. Reading: Addison-Wesley, c2000. 411 p. (Java series) ISBN 0201310090 Número de Chamada: 005.133 L433c 2. ed.

33
33

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Sumário 1 a Definição de sistemas paralelos e distribuídos 44 Programação Paralela e Distribuída -
Sumário
1 a
Definição de sistemas paralelos e distribuídos
44
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Múltiplos processadores conectados por uma memória compartilhada

Memória

Compartilhada

barramento

CPU CPU CPU CPU MEM MEM MEM MEM LOCAL LOCAL LOCAL LOCAL
CPU
CPU
CPU
CPU
MEM
MEM
MEM
MEM
LOCAL
LOCAL
LOCAL
LOCAL

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

55
55

Sistema Paralelo

Sistema Distribuído Múltiplos processadores conectados por uma rede de comunicação Troca de mensagens Rede de
Sistema Distribuído
Múltiplos processadores conectados por uma rede de comunicação
Troca de mensagens
Rede de
Comunicação
Segundo (Garg, 2004), são sistemas compostos por
múltiplos processadores conectados por uma rede de
comunicação, sendo a rede de comunicação uma LAN
(Ethernet) ou WAN (Internet). Neste tipo de sistema os
processadores se comunicam por troca de mensagens
(não por memória compartilhada)
66
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Necessidades

Sistemas paralelos e distribuídos

Necessitam de ferramentas e técnicas Distintas das utilizadas em software sequencial

77
77

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Distribuído x Paralelo (1)

Em relação ao hardware,

Se pensarmos em desempenho, é melhor termos sistemas distribuídos ou paralelos? R: combinação Computadores multiprocessados conectados por uma rede

Rede de Comunicação Memória Memória Compartilhada Compartilhada CPU CPU CPU CPU CPU CPU CPU CPU
Rede de
Comunicação
Memória
Memória
Compartilhada
Compartilhada
CPU
CPU
CPU
CPU
CPU
CPU
CPU
CPU
CPU
CPU
CPU
CPU
MEM
MEM
MEM
MEM
MEM
MEM
MEM
MEM
MEM
MEM
MEM
MEM
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
88
88

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Distribuído x Paralelo (2)

Por que não sistemas completamente paralelos?

Escalabilidade Modularidade e heterogeneidade Compartilhamento de dados Compartilhamento de recursos Estrutura distribuída por si Confiabilidade Baixo custo

99
99

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Distribuído x Paralelo (3)

Por que não sistemas completamente distribuídos?

Melhor desempenho no processamento local É mais rápido atualizar uma memória local do que enviar uma mensagem para outro processador, especialmente quando o valor de uma variável deve ser comunicado para vários processadores

1010
1010

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Distribuído x Paralelo (4)

Em relação ao software (API programação),

Pode ser independente do hardware?

Na realidade, reflete a estrutura de hardware

Modelo de objetos distribuídos (ex. RMI) tem-se Processos que se comunicam por mensagens

Processos que podem ter várias threads Threads que se comunicam por memória compartilhada

Memória Memória Compartilhada Compartilhada CPU CPU CPU CPU CPU CPU CPU CPU CPU CPU CPU
Memória
Memória
Compartilhada
Compartilhada
CPU
CPU
CPU
CPU
CPU
CPU
CPU
CPU
CPU
CPU
CPU
CPU
MEM
MEM
MEM
MEM
MEM
MEM
MEM
MEM
MEM
MEM
MEM
MEM
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
Rede de Comunicação
Rede de
Comunicação
1111
1111
LOCAL LOCAL LOCAL LOCAL Rede de Comunicação 1111 Programação Paralela e Distribuída - Fundamentos/UTFPR

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Sumário 1 b Conceitos: programa, processo e thread 1212 Programação Paralela e Distribuída - Fundamentos/UTFPR
Sumário
1 b
Conceitos: programa, processo e thread
1212
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Programa, processo, thread

Programa conjunto de instruções numa linguagem de alto nível ou de máquina

Processo resulta da execução do programa, tem um ambiente de execução autocontido e privado.

O que o usuário enxerga como aplicação ou sistema, normalmente é composto por vários processos Sequencial = 1 processo Concorrente = vários processos

programa
programa

Processo 1

Processo 2

Processo n n

execução

Processo 1 Processo 2 Processo n e x e c u ç ã o 1313 Programação
Processo 1 Processo 2 Processo n e x e c u ç ã o 1313 Programação
1313
1313

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Programa, processo, thread

Thread são chamadas de processos peso-pena

Tanto threads como processos provêm um ambiente de execução ou contexto de execução

Multithread é uma característica essencial de Java

Toda aplicação possui pelo menos uma thread main

Threads compartilham o mesmo "espaço de endereçamento“ (memória)

É mais rápido chavear a execução entre threads do que entre processos.

Threads compartilham recursos do processo: memória e arquivos abertos.

1414
1414

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Programa, processo e thread

Uma thread recebe recursos próprios durante a execução:

uma pilha (stack) de execução para poder chamar métodos, passar parâmetros, alocar variáveis locais um "Program Counter" Estes elementos formam o contexto de execução da thread

Estes elementos formam o contexto de execução da thread 1515 Programação Paralela e Distribuída -
1515
1515

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Programa, processo, thread Stack: armazena o estado de cada invocação de método: Processos que compartilham
Programa, processo, thread
Stack: armazena o estado de
cada invocação de método:
Processos que compartilham código e
dados são chamados de threads, são
também chamados de processos lightweight
variáveis locais, argumentos,
Program Counter Register
retorno e dispatch de
exceções. São vários frames
empilhados stack overflow
PCR
PCR
PCR
Stack
Stack
Stack
Contexto de
execução de uma
thread
Thread 1
Thread 2
Thread 3
Heap: armazena instâncias de
heap
objetos criadas em tempo de
execução. Também armazena
arrays OutOfMemoryError
Compartilhado
pelas threads
Method area
Method area: informações da classe (nome,
modificadores), superclasse, atributos e seus
modificadores, atributos estáticos com valores,
métodos e seus modificadores, bytecodes
1616
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Exemplos de threads

Threads – demos

Links na página do curso

http://www.doc.ic.ac.uk/~jnm/concurrency/classes/ThreadDemo/ThreadDemo.html

http://www.dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/threads1.html

1717
1717

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Sumário 1 c Criação de Processos/Threads 1818 Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar
Sumário
1 c
Criação de Processos/Threads
1818
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
UNIX, C++ ◊ Criação de processos Processo pai pid = fork(); if (pid == 0)
UNIX, C++
Criação de processos
Processo pai
pid = fork();
if (pid == 0) {
cout << “processo filho”;
else
cout << “processo pai”;
programa
pid = fork();
if (pid == 0) {
cout << “processo filho”;
else
cout << “processo pai”;
Processo filho
pid = fork();
if (pid == 0) {
cout << “processo filho”;
else
cout << “processo pai”;
1919
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Criação de threads em Java

Implements Runnable

Runnable <<realizes>> MinhaThread +run():void
Runnable
<<realizes>>
MinhaThread
+run():void

Possibilita estender outra classe

2020
2020

Há 2 métodos

Extends Thread

Thread MinhaThread +run():void
Thread
MinhaThread
+run():void

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Exemplo de criação de Thread por extends

public class MinhaThread extends Thread { public void run() { System.out.println(“Ola!!!!”);

}

}

public class Main { public static void main(String[] args) { MinhaThread t = new MinhaThread(); t.start();

}

}

:Main
:Main

new

start()

new start()
new start()
new start()
new start()
new start()
new start()

:MinhaThread

(); } } :Main new start() :MinhaThread Programação Paralela e Distribuída - Fundamentos/UTFPR

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

run()

2121
2121

Criação de threads em Java

Exemplo de criação de Thread por implements

public class MinhaThread implements Runnable { public void run() { System.out.println(“Ola!!!!”);

}

}

public class Main { public static void main(String[] args) { MinhaThread t = new MinhaThread(); Thread t2 = new Thread(t);

t2.start();

}

}

:Main
:Main

new

start()

new start()
new start()
new start()
new start()
new start()
new start()

:MinhaThread

(); } } :Main new start() :MinhaThread Programação Paralela e Distribuída - Fundamentos/UTFPR

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

run()

2222
2222

Criação de threads em Java

Criação de threads em Java

Exemplo básico: threads contadoras

Código fonte e .jar disponível em http://www.dainf.ct.utfpr.edu.br/~tacla/JAVARepositorio/JThreads/JThreadContadoras

Duas threads são criadas, cada uma conta até 1.000. Os resultados podem aparecer intercalados.

Para compilar e executar Ir ao subdiretório src/jthread Salvar o arquivo em Main.java <dir>/jthread/ Lance o shell: executar cmd Posicione no diretório <dir> Compile: javac jthread/Main.java Execute: java -cp . jthread/Main

Para executar somente Ir ao subdiretório dist Salve o arquivo .jar em <dir> Lance o shell: executar cmd Posicione no diretório <dir> Execute: java -jar JThreadContadoras.jar

JAVARepositorio\JThreads\JThreadContadoras

2323
2323

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Criação de Threads em Java ◊Exemplo básico: threads contadoras class MinhaThread implements Runnable { public
Criação de Threads em Java
◊Exemplo básico: threads contadoras
class MinhaThread implements Runnable {
public void run() {
// a interface Runnable exige a implementação do método run
String name = Thread.currentThread().getName();
System.out.println(name + " rodando");
for (int i=0;i < 1000; i++) {
System.out.println(name + ": " + i);
}
System.out.println(name + " FIM ***");
}
}
public class Main {
public static void main(String[] args) {
System.out.println("INICIO DA THREAD MAIN ***");
Thread t1 = new Thread(new MinhaThread(), "thread 1");
Thread t2 = new Thread(new MinhaThread(), "\t\tthread 2");
t1.start();
t2.start();
}
}
2424
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Criação de Threads em Java ◊Exemplo básico: threads contadoras Quem faz o chaveamento de contexto?
Criação de Threads em Java
◊Exemplo básico: threads contadoras
Quem faz o chaveamento de contexto?
2525
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Criação de threads em Java

Exercício 1: modifique o programa das threads contadoras de forma a criá-las estendendo a classe Thread

class MinhaThread implements Runnable {

Exercício 2: criar várias threads (> 4) e observar o chaveamento de contexto.

2626
2626

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Sumário 1 d Yield, Sleep e Join 2727 Programação Paralela e Distribuída - Fundamentos/UTFPR Prof.
Sumário
1 d
Yield, Sleep e Join
2727
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Java THREADS: YIELD ◊ YIELD suspende a execução da thread atual e permite que outra
Java THREADS: YIELD
◊ YIELD
suspende a execução da thread atual
e permite que outra ocupe o
processador.
As flechas pontilhadas indicam swap.
O label das flechas indicam omotivo do swap:
:Main
Swap: escalonador do SO;
yield(): a chamada ao método causou a mudança.
new
t1:MinhaThread
new
t2:MinhaThread
start()
start()
Início do run()
swap
Início do run()
swap
yield()
yield()
2828
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Java THREADS: YIELD ◊ Exemplo de utilização de yield class MinhaThread implements Runnable { public
Java THREADS: YIELD
◊ Exemplo de utilização de yield
class MinhaThread implements Runnable {
public void run() {
// a interface Runnable exige a implementação do método run
String name = Thread.currentThread().getName();
System.out.println(name + " rodando");
for (int i=0;i < 1000; i++) {
System.out.println(name + ": " + i);
// eh possivel passar o controle para outra thread implicitamente
Thread.yield();
}
System.out.println(name + " FIM ***");
}
}
public class Main {
public static void main(String[] args) {
System.out.println("INICIO DA THREAD MAIN ***");
Thread t1 = new Thread(new MinhaThread(), "thread 1");
Thread t2 = new Thread(new MinhaThread(), "\t\tthread 2");
t1.start();
t2.start();
}
}
2929
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Java THREADS: YIELD

Exercício: no exemplo das threads contadoras, habilite o yield fazendo: java –jar JThreadContadoras.jar YIELD

o yield fazendo: java –jar JThreadContadoras.jar YIELD 3030 Programação Paralela e Distribuída -
3030
3030

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Java Threads: SLEEP ◊ Sleep: suspende a execução da thread por um período Libera o
Java Threads: SLEEP
Sleep: suspende a execução da thread por um período
Libera o processador para outras threads
Faz a thread dormir por milisegundos ou nanosegundos
Tempo de sleep não é preciso, depende do SO
No exemplo das threads contadoras, cada
thread dorme 2s a cada 3 contagens.
Execute-o fazendo:
java –jar JThreadContadoras.jar NO 2000
if (i%3==0) {
try {
thread.sleep(2000); // dorme 2 seg
catch (InterruptedException e) {}
}
3131
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Java THREADS: SLEEP

SLEEP

suspende a execução da thread atual por pelo menos x milisegundos e permite que outra ocupe o processador.

:Main new t1:MinhaThread new t2:MinhaThread start() start() Início do run() swap Início do run() swap
:Main
new
t1:MinhaThread
new
t2:MinhaThread
start()
start()
Início do run()
swap
Início do run()
swap
sleep(2000)
Timed
waiting
swap
3232
3232

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Java Threads: SLEEP ◊ Exercício [JAVA]: faça a simulação de um cruzamento controlado por dois
Java Threads: SLEEP
Exercício [JAVA]: faça a simulação de um cruzamento
controlado por dois semáforos utilizando apenas sleep para
controlar os tempos de verde, amarelo e vermelho.
Observe que o sleep fará sinaleiros não sincronizados.
Para simplesmente executá-lo, ver próximo slide.
Sol. JAVARepositorio\JThreads\JCruzamento-v1
3333
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Java Threads: SLEEP ◊ Para executar o cruzamento fazer: ◊ Baixar o .jar de
Java Threads: SLEEP
◊ Para executar o cruzamento fazer:
◊ Baixar o .jar de
http://www.dainf.ct.utfpr.edu.br/~tacla/JAVARepositorio/JThreads/JCruzamento-v1/dist/
>java -jar JCruzamento.jar
Estado SEM1:VERMELHO
Estado SEM2:VERDE
Estado SEM1:VERDE
Estado SEM2:AMARELO
Estado SEM2:VERMELHO
Estado SEM1:AMARELO
Estado SEM2:VERDE
As linhas em destaque mostram que o semáforo SEM1
e o SEM2 ficaram verde ao mesmo tempo!!!
3434
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Java Threads: JOIN ◊ Thread.join(): permite que uma thread espere pelo término de duas ou
Java Threads: JOIN
◊ Thread.join(): permite que uma thread espere pelo
término de duas ou mais threads
:Main
new
t1:MinhaThread
new
t2:MinhaThread
start()
start()
join (t1, t2)
Início do run()
swap
Início do run()
swap
waiting
fim t1
fim t2
Fim join (t1, t2)
A thread main fica a espera de t1 e t2
3535
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Java Threads: JOIN public static void main (String[] args) { System.out.println("INICIO DA THREAD MAIN ***");
Java Threads: JOIN
public static void main (String[] args) {
System.out.println("INICIO DA THREAD MAIN ***");
Thread t1 = new Thread(new MinhaThread(), "thread 1");
Thread t2 = new Thread(new MinhaThread(), "\t\tthread 2");
t1.start();
t2.start();
try {
t1.join(); // a thread main aguarda o término de t1
t2.join(); // a thread main aguarda o término de t2
} catch (InterruptedException e) {
System.out.println(“interrupcao");
}
System.out.println("*** As duas threads encerraram a
contagem ***");
// outras coisas da thread main
}
3636
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Java Threads: JOIN

JOIN: “une” as execuções das threads

No exemplo das threads contadoras, para testar o JOIN, faça:

java –jar JThreadContadoras.jar NO 2000 JOIN

3737
3737

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Sumário 1 e Prioridade entre threads 3838 Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar
Sumário
1 e
Prioridade entre threads
3838
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Prioridade entre threads

Qual thread é escolhida para rodar?

Depende

da implementação da JVM (ex. se utiliza threads nativas do SO) da prioridade da thread da política/algoritmo de escalonamento do sistema operacional (ex. round-robin = rodízio por fatia de tempo = quantum)

3939
3939

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Prioridade entre threads

Exemplo: escalonamento no Linux

[fonte http://www.inf.pucrs.br/~celso/SchedulerLinuxWindows.pdf]

Cada processo possui uma prioridade, recalculada dinamicamente. O escalonador dá a CPU ao processo de maior prioridade O escalonador é preemptivo Para processos interativos (I/O bound) -> round-robin Para processos tempo-real -> FCFS (first come, first served)

4040
4040

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Prioridade entre Threads

Windows (2000/NT/XP) – ESCALONAMENTO

[fonte http://www.inf.pucrs.br/~celso/SchedulerLinuxWindows.pdf]

No Windows 2000/XP o escalonador utiliza múltiplas filas e as threads interativos (I/O bound) possuem prioridade sobre os CPU bound.

O escalonamento é baseado em prioridades. Cada thread possui uma prioridade, que varia de 0 a 31 (0 é a menor e 31 a maior).

A prioridade 0 é atribuída a uma thread especial, chamada zero thread, que é responsável por zerar as páginas livres no sistema. Somente esta thread pode receber a prioridade 0.

As prioridades definem três classes de threads:

Real time: prioridades de 16 a 31; Normal: prioridades de 0 a 15. Existe ainda uma classe especial chamada idle, a de mais baixa prioridade. Threads nesta classe somente executam quando não existem outras threads aptas (portanto, threads dessa classe não interferem na performance – não causam overhead).

4141
4141

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Prioridade entre Threads

Windows (2000/NT/XP) – ESCALONAMENTO

O escalonador escolhe sempre a thread de maior prioridade. As threads da classe real time executam até terminar ou se bloquear (FCFS). As threads com prioridade normal (0 a 15) recebem fatias de tempo (RR). no Windows 2000 professional, a fatia de tempo é de 20 ms (para favorecer a interatividade). no Windows 2000 Server, a fatia é de 120 ms (para gerar menos trocas de contexto).

Cada thread recebe uma prioridade base ao ser criada. Para os processos de tempo real (prioridade entre 16 e 31) esta prioridade não se altera. Além disso, uma thread tem uma prioridade inicial que indica sua prioridade relativa dentro do processo.

Threads com prioridade entre 0 e 15 têm a prioridade ajustada em tempo de execução:

Preemptadas por operações de I/0 recebem um bônus de aumento, que depende do periférico (ex. 1 para disco e 6 para teclado). Preemptadas por esgotar o quantum: prioridade reduzida.

4242
4242

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Prioridade entre threads

Mapeamento de threads

Há de se considerar o mapeamento das threads da JVM para threads nativas do

sistema operacional. Por exemplo, a JavaHotSpot VM na Solaris mapeia uma thread

Java em uma thread nativa.

Maiores detalhes em http://java.sun.com/j2se/1.5.0/docs/guide/vm/thread-priorities.html

http://msdn.microsoft.com/en-us/library/ms685100(VS.85).aspx

As prioridades das Threads setadas no código Java são lógicas e dependem da implementação da JVM:

public final int getPriority()

MAX_PRIORITY = 10 constante inteira

NORM_PRIORITY = 5 prioridade atribuída por default

public final void setPriority(int newPriority)

MIN_PRIORITY = 1 constante inteira

4343
4343

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Exercício: modificar a prioridade das threads contadoras e observar efeito na execução. Os dois últimos parâmetros modificam respectivamente as prioridades da thread 1 e 2. Recorda-se que a prioridade deve estar no intervalo [1, 10]

No exemplo das threads contadoras, para testar o a prioridade, faça:

java –jar JThreadContadoras.jar OFF 0 OFF 1 10

 
 

Prioridade thread 1

   

Prioridade thread 2

Código fonte e jar disponíveis em http://www.dainf.ct.utfpr.edu.br/~tacla/JAVARepositorio/JThreads/JThreadContadoras/

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

4444
4444

Prioridade entre threads

Prioridade entre threads

Exercício: considere um simulador de corridas de fórmula 1 que simula uma disputa entre dois pilotos: Schumacker e Barrichelo.

Cada carro funciona de forma independente O tempo de cada volta é dado por um valor randômico. O programa deve esperar por este tempo sem fazer nada para então iniciar a próxima volta Ao final da corrida (quando os dois carros completam 5 voltas), o simulador mostra o tempo acumulado para cada um dos pilotos e aponta o vencedor ou empate.

Responda

Que comandos da linguagem Java você utilizaria para resolver cada um dos itens acima?

JAVARepositorio\JThreads\JCarrosCorrida

4545
4545

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Prioridade entre threads

O código abaixo é uma solução do problema anterior. [JAVA] Altere o programa atribuindo maior prioridade a uma das threads (Schumaker ou Barrichelo). [TELEINFO] Execute o .jar for fun!

Código fonte e .jar disponíveis em http://www.dainf.ct.utfpr.edu.br/~tacla/JAVARepositorio/JThreads/JCarrosCorrida/

* No exemplo seguinte, simulamos dois carros de corrida: Schumacker e Barrichelo.

* Cada carro funciona de forma independente na sua thread e demora x milisegundos

* para percorrer um determinado trecho da pista (x é um valor aleatório).

* Para simular este tempo, utilizamos o método Sleep. Na thread Main aguardamos que

* os dois carros terminem a prova para encerrar a corrida. Isto é feito através do join.

*

* * Rodar a partir da linha de comando

* ===================================

* 1. Salve este arquivo em <dir>/jcarroscorrida/

* 2. Lance o shell: executar -> cmd

* 3. posicione no diretório <dir>

* 4. compile: javac jcarroscorrida/Main.java

* 5. execute: java -cp . jcarroscorrida/Main

*/

JAVARepositorio\JThreads\JCarrosCorrida

4646
4646

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Sumário 1 f Compartilhamento de memória 4747 Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar
Sumário
1 f
Compartilhamento de memória
4747
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Compartilhamento de memória

Compartilhamento de memória é um subtópico de comunicação inter-processos (IPC)

fila de mensagens (SO) pipeline (SO) proc1 >> proc2 >> proc 3 área de memória compartilhada (SO) POSIX, threads envio de mensagens (rede) CORBA, JRMI, RPC, MPI

Threads se comunicam por compartilhamento de memória

Atributos (membro de classe e de instância) Objetos compartilhados

4848
4848

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Exemplo de compartilhamento de memória class AreaMem { static String compartilhada= Thread.currentThread().getName();;
Exemplo de compartilhamento de memória
class AreaMem {
static String compartilhada= Thread.currentThread().getName();;
}
class Escritora extends Thread {
public void run() {
AreaMem.compartilhada = Thread.currentThread().getName();
}
}
public class Main {
public static void main(String[] args) {
Escritora E0 = new Escritora();
Escritora E1 = new Escritora();
E0.start();
E1.start();
System.out.println("Compartilhada = " + AreaMem.compartilhada);
}
}
http://www.dainf.ct.utfpr.edu.br/~tacla/JAVARepositorio/JThreads/JCompartMemStaticSimples/
O atributo estático AreaMem.compartilhada é compartilhado entre as threads E0, E1 e main
4949
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Exercício

Execute várias vezes o código do slide anterior

Anote os valores impressos

Qual a explicação?

5050
5050

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Um dos cenários possíveis de execução; o valor impresso é “main” main:Thread c=“main” new E0:Thread
Um dos cenários possíveis de execução; o valor impresso é “main”
main:Thread
c=“main”
new
E0:Thread
E1:Thread
start()
start()
print c
run()
X
run()
c=“Thread-0”
c=“Thread-1”
X
X

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

5151
5151

Cenários de execução do exemplo

Exemplo por atributo estático public class Main extends Thread { static int c = 0;
Exemplo por atributo estático
public class Main extends Thread {
static int
c = 0;
// compartilhado
private int ini, fim; // nao compartilhados
public Main(int ini, int fim) {
this.ini = ini;
this.fim = fim;
}
public void run() {
System.out.println(Thread.currentThread().getName() + " !!! wait ");
while (c >= ini && c <= fim) {
System.out.println(Thread.currentThread().getName() + " antes " + c);
c = (int)(Math.random()*10);
System.out.println(Thread.currentThread().getName() + " depois " + c);
}
System.out.println(Thread.currentThread().getName() + " !!! fim ");
}
public static void main(String[] args) {
new Main(0, 4).start();
new Main(5, 10).start();
}
}
JAVARepositorio\JThreads\JCompartMemStatic
5252
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Cenário de execução do exemplo main:Main <<create>> Thread-0:Main Thread-1:Main start() start()
Cenário de execução do exemplo
main:Main
<<create>>
Thread-0:Main
Thread-1:Main
start()
start()
swap
run()
X
0
≤≤≤≤ c ≤≤≤≤ 4
c:=2
0
≤≤≤≤ c ≤≤≤≤ 4
c:=5
swap
X
5
≤≤≤≤ c ≤≤≤≤ 10
c:=6
5
≤≤≤≤ c ≤≤≤≤ 10
c:=2
O atributo estático c
X
é compartilhado pelas
threadas
5353
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Exercício main:Main Explique porque a seguinte sequência de mensagens não é possível <<create>>
Exercício
main:Main
Explique porque a seguinte
sequência de mensagens não é
possível
<<create>>
Thread-0:Main
Thread-1:Main
start()
start()
swap
run()
X
0
≤≤≤≤ c ≤≤≤≤ 4
c:=2
swap
run()
swap
5
≤≤≤≤ c ≤≤≤≤ 10
0
≤≤≤≤ c ≤≤≤≤ 4
c:=5
swap
X
5
≤≤≤≤ c ≤≤≤≤ 10
c:=6
5
≤≤≤≤ c ≤≤≤≤ 10
c:=2
X
5454
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Para a classe abaixo

class Schedule static int x = 0; static int y = 0; public static int op1() {

x = 1;

return y;

}

public static int op2() {

y = 2;

return 3*x;

}

Exercício

Objetivo: entender o compartilhamento de memória por atributos estáticos

Se uma thread chama op1 e outra, op2, que resultados podem ser retornados pelos métodos op1 e op2?

(Vijay K. Garg, 2004, p. 15)

5555
5555

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Exemplo por objeto compartilhado class Conta { int saldo = 0; Objeto compartilhado } class
Exemplo por objeto compartilhado
class Conta {
int saldo = 0;
Objeto compartilhado
}
class Retirada extends Thread {
private Conta c;
public Retirada(Conta c) {
this.c = c;
class Deposito extends Thread {
private Conta c;
public Deposito(Conta c) {
this.c = c;
}
}
public void run() {
int vlrs[] = {10, 20, 30, 40, 50, 60};
for (int i=0; i <vlrs.length; i++)
c.saldo -= vlrs[i];
public void run() {
int vlrs[] = {40, 50, 60, 10, 20, 30};
for (int i=0; i <vlrs.length; i++)
c.saldo += vlrs[i];
}
}
}
}
public class Main {
public static void main(String[] args) {
Conta c = new Conta();
Thread d = new Deposito(c);
Thread r = new Retirada(c);
d.start();
r.start();
try {
d.join();
r.join();
} catch (InterruptedException e) { }
System.out.println("Saldo=" + c.saldo);
}
}
http://www.dainf.ct.utfpr.edu.br/~tacla/JAVARepositorio/JThreads/JCompartMemObjetoCC/
5656
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Exercício

Faça uma classe Java que faça busca paralela num array de inteiros. A classe deve implementar o método:

public static int busca(int x, int[] A, int nThreads)

O método cria nThreads Estas threads devem compartilhar o objeto A. Cada thread busca pelo inteiro x em uma parte de A, por exemplo, da posição 0 até a 10, outra da 11 a 20,

Se uma das threads encontra x, então retorna-se o índice i, tal que A[i] = x Caso contrário, o método retorna -1 Quando uma das threads encontra o número x, as outras devem parar a busca!

sol. JAVARepositorio\JThreads\JBuscaParalela

5757
5757

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Sumário 1 g Máquina de estados de uma thread 5858 Programação Paralela e Distribuída -
Sumário
1 g
Máquina de estados de uma thread
5858
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Estados de uma thread As transições observadas até o momento estão em destaque Object.wait(timeout)
Estados de uma thread
As transições observadas até o momento estão em destaque
Object.wait(timeout)
Thread.join(timeout)
TIMED WAITING
Thread.sleep(delay)
Object.notify()
Object.notifyAll()
join thread termina
fim do sleep
Obteu lock
new()
start()
NEW
RUNNABLE
BLOCKED
Object.notify()
Escolhida pelo
join threads terminam
Object.notifyAll()
scheduler
Thread.yield()
swap do scheduler
RUNNING
WAITING
TERMINATED
Object.wait()
Thread.join()
Fim do método run()
Synchronized(obj)
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.State.html
5959
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Estado de uma thread: detalhe do runnable RUNNING Thread.yield() Escolhida pelo scheduler swap do scheduler
Estado de uma thread: detalhe do runnable
RUNNING
Thread.yield()
Escolhida pelo scheduler
swap do scheduler
Em runnable, a thread pode ser
escolhida pelo scheduler
para entrar em execução. Uma vez em
execução, pode liberar o processador
por yield ou por swap do scheduler.
RUNNABLE
6060
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Sumário

2
2

PROBLEMAS DE CONCORRÊNCIA

6161
6161

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Sumário 2 a Problemas de Concorrência 6262 Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar
Sumário
2 a
Problemas de Concorrência
6262
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Problemas de concorrência

Processos compartilham dados

Sincronizar acesso aos dados é necessário

Exemplo

x é uma variável compartilhada (inicialmente zero)

Thread T0 faz x := x + 1 Thread T1 faz x := x + 1 x deve ser 2 ao final

Porém, se x := x + 1 não for uma operação atômica

6363
6363

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

x = x + 1 em código de máquina (inicial x=0)

LD R, x

load registrador R com x

INC R

incrementar R

ST R, x

store R em x

A execução de T0 e T1 é intercalada

P0: LD R, xR = 0

R = 0
R
= 0

P0: INC RR =1

R =1
R
=1
 
  P1: LD R, x R = 0

P1: LD R, x

R

= 0

P1: INC R R =1

P1: INC R

R

=1

P0: ST R, x x =1  

P0: ST R, x

x

=1

 
 
  P1: ST R, x x =1

P1: ST R, x

x

=1

Registrador R

0 1 0 0 1
0
1
0
0
1

Variável x

0 1 1
0
1
1

Resultado final: x = 1 problema da atualização perdida

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

6464
6464

RACE CONDITION: atualização perdida

Problemas de concorrência

x := x + 1 deve ser executada atomicamente

Região/Seção crítica necessida atomicidade

Para garantir atomicidade, exclusão mútua

Recurso compartilhado
Recurso
compartilhado

Processo 1

Processo 2

Quem ganha a disputa?

processos querem o recurso, mas só um pode utilizá-lo, caso contrário o recurso pode ficar num estado inconsistente

6565
6565

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

 

RACE CONDITION: atualização perdida

 

CC = Conta corrente Saldo: R$ 100,00

 

Transação T1:

Transação T1: Transação T2:

Transação T2:

crédito de R$5,00

crédito de 10% de juros

 

Situação desejada:

 

1)

2)

Aplica-se o juros credita-se R$ 5,00

Funcionamento das transações

1)

2)

3)

s:=CC.getSaldo() Crédito na variável s CC.setSaldo(s)

Saldo da conta deve ser:

(R$100,00 * 1,1) + 5,00 = R$ 115,00

Problemas:

Leitura suja

Atualização perdida

 
6666
6666

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

 

Quando uma transação sobrescreve valores produzidos por outra

TRANSAÇÃO T1 Creditar R$ 5,00

TRANSAÇÃO T2 Juros de 10%

S:= CC.getSaldo() S:= S + 5

// R$100 // S = 105

 
 

S = CC.getSaldo( ); S = S * 1,10; CC.setSaldo(S);

// R$100 // R$ 110,00 // R$ 110,00

CC.setSaldo(S) // R$105

 
110,00 // R$ 110,00 CC.setSaldo(S) // R$105   Sobrescreve o valor produzido por T2 Saldo final

Sobrescreve o valor produzido por T2 Saldo final = R$ 105,00

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

6767
6767

RACE CONDITION: atualização perdida

Quando uma transação lê valores intermediários de outro transação - atributos que estão sendo modificados em outra transação

Transfere R$100,00 da Conta A para a conta B

Relatório com o saldo total das agências

TRANSAÇÃO T1

TRANSAÇÃO T2

A.retirar(100)

 

total = A.saldo( ); // R$100 total = total + B.saldo( ); // R$300

 

Mostrar total = R$ 400,00

B.depositar(100)

 

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

6868
6868

RACE CONDITION: leitura suja

Saldo A = R$ 200,00 Saldo B = R$ 300,00 TOTAL = R$ 500,00

Após transferência

Saldo A = R$ 100,00 Saldo B = R$ 400,00 TOTAL = R$ 500,00

CONCORRÊNCIA

Exemplo de leitura suja/atualização perdida: executar o código abaixo e observar que o número apontado pelo contador central difere da soma dos contadores locais devido aos problemas de leitura suja e atualização perdida.

Códigos fonte e .jar disponíveis em http://www.dainf.ct.utfpr.edu.br/~tacla/JAVARepositorio/JThreads/JRaceConditionRoletas/

Contador central

Contador central 160.000.000 40.000.000 Atualizado pelas duas roletas de

160.000.000

40.000.000 Atualizado pelas duas roletas de forma concorrente
40.000.000
Atualizado pelas
duas roletas de
forma concorrente
Atualizado pelas duas roletas de forma concorrente 120.000.000 Roleta e contador local 6969 Programação

120.000.000

Roleta e contador local

6969
6969

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Sumário 2 b Vivacidade: deadlock, livelock e starvation 7070 Programação Paralela e Distribuída -
Sumário
2 b
Vivacidade: deadlock, livelock e starvation
7070
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Vivacidade

VIVACIDADE: um pedido de uma thread para entrar/acessar uma seção crítica será atendido mais cedo ou mais tarde

DEADLOCK: uma thread t1 bloqueia a espera de uma seção crítica ocupada por t2 que, por sua vez, está bloqueada a espera da seção crítica ocupada por t1 grafo wait-for cíclico

STARVATION: quando uma thread solicita entrada numa seção crítica e nunca é atendida (ex. porque as outras tem maior prioridade)

LIVELOCK: duas threads não conseguem avançar porque uma muda seu estado em resposta à mudança de estado da outra (ex. duas pessoas no corredor que sempre escolhem o mesmo lado para desviarem).

7171
7171

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Exemplo de deadlock

DEADLOCK: filósofos podem bloquear-se.

? ?
?
?
deadlock ◊ DEADLOCK : filósofos podem bloquear-se. ? ? Applet demo disponível em

Applet demo disponível em http://www.doc.ic.ac.uk/~jnm/concurrency/classes/Diners/Diners.html /

7272
7272

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Exemplo de starvation ◊ STARVATION: um dos filósofos nunca come porque o outro tem maior
Exemplo de starvation
STARVATION: um dos filósofos nunca come porque o outro
tem maior prioridade.
Prioridade por
ser o mais sábio
7373
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Exemplo de livelock ◊ LIVELOCK: filósofos podem bloquear-se porque mudam de estado continuament em função
Exemplo de livelock
LIVELOCK: filósofos podem bloquear-se porque mudam de
estado continuament em função do outro.
7474
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Problema dos filósofos 1. Só um dos filósofos decide comer 2. Os dois decidem comer
Problema dos filósofos
1. Só um dos filósofos decide comer
2. Os dois decidem comer ao mesmo tempo, cada um pega um pauzinho
P1 c/ F1
P1 c/ F21
Pauzinho 1
Filósofo 2
F1
F1
F2
F2
pega
decide
F1 e F2
pensam
termina
decide
pega
de comer
Filósofo 1
2 pauzinhos comer
comer
2 pauzinhos
termina de
comer
Pauzinho 2
P2 c/ F1
P2 c/ F2
7575
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Problema dos filósofos

Solução para o problema dos filósofos: coordenar as ações

Um dos filósofos devem solicitar os recursos na ordem inversa dos outros Ex. todos pegam o objeto da esquerda e depois o da direita. Facilmente visível com dois filósofos

7676
7676

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Problema dos filósofos

SOLUÇÃO: coordenar as ações. Inverter a ordem.

WAIT◊ SOLUÇÃO : coordenar as ações. Inverter a ordem. 7777 Programação Paralela e Distribuída -

WAIT
SOLUÇÃO : coordenar as ações. Inverter a ordem. WAIT 7777 Programação Paralela e Distribuída -
SOLUÇÃO : coordenar as ações. Inverter a ordem. WAIT 7777 Programação Paralela e Distribuída -
7777
7777

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Solução para filósofos Primeiro o p1 depois o p2 Se os dois decidem comer ao
Solução para filósofos
Primeiro o p1 depois o p2
Se os dois decidem comer ao mesmo tempo,
somente um deles conseguirá pegar o pauzinho
1
P1 c/ F1
P1 c/ F21
Pauzinho 1
Filósofo 2
termina
de comer
F1
F2
decide
decide
P1 e P2
C/ F1
comer
F1 e F2
pensam
comer
Filósofo 1
P1 E P2
c/ F2
termina de
comer
Pauzinho 2
7878
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Problema dos filósofos ◊ Exercício Verificar se a solução apresentada funciona para 4 filósofos sendo

Problema dos filósofos

Exercício

Verificar se a solução apresentada funciona para 4 filósofos sendo o f2 aquele que pega na ordem invertida. Represente em um diagrama de seqüência a situação na qual todos tentam pegar os pauzinhos ao mesmo tempo.

f1 p1 p4 f2 f4 p3 p2 f3
f1
p1
p4
f2
f4
p3
p2
f3
7979
7979

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Sumário 2 c Soluções aos problemas de concorrência 8080 Programação Paralela e Distribuída - Fundamentos/UTFPR
Sumário
2 c
Soluções aos problemas de concorrência
8080
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

SOLUÇÕES PARA CONCORRÊNCIA

Como resolver os problemas de acesso à seção crítica?

Algoritmos de exclusão mútua (mutex) Busy-wait (Peterson)

Exclusão mútua por hardware Desabilitar interrupções instruções de máquina atômicas de mais alto-nível

Primitivas de sincronização Semáforos

Monitores

monitor
monitor
8181
8181

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

MUTEX BUSY-WAIT ◊ BUSY-WAIT: um processo verifica continuamente se pode entrar na seção crítica desperdiçando
MUTEX BUSY-WAIT
BUSY-WAIT: um processo verifica continuamente se pode
entrar na seção crítica desperdiçando assim ciclos do
processador.
public class Lock1 implements Lock {
boolean livre = true;
public void requestSC(int i ) {
while (!livre); // busy wait
livre = false;
}
public void releaseSC(int i) {
livre = true;
}
}
JAVARepositorio\JThreads\JExclusaoMutuaLock\src\jexclusaomutualock/Lock1.java
8282
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

MUTEX BUSY-WAIT

Algoritmo de exclusão mútua de Peterson

Três versões incrementais

1. não garante exclusão mútua

2. Pode entrar em deadlock

3. Alternância estrita

Versão final Deadlock (livre de impasse) Starvation (livre de inanição) Vivacidade

Busy-wait: solução de Peterson

Exercício: algoritmo de Dekker

Sujeito a deadlock? Sujeito a Starvation? Possui a propriedade de vivacidade?

8383
8383

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

MUTEX por HARDWARE

Que soluções existem em hardware para o problema de exclusão mútua?

Desabilitar interrupções: antes de entrar na SC, o processo desabilita as interruções Em máquinas monoprocessador pode funcionar com alguns incovenientes interrupções do clock (time-slice) ficam desabilitadas mas, em máquinas multiprocessadores? É possível desabilitar interrupções em todos os processadores?

Instruções atômicas mais abstratas fornecidas pelo hardware Test and set Swap

8484
8484

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

SEMÁFOROS

SEMÁFORO (Dijkstra): é uma primitiva de sincronização de acesso à seção crítica que soluciona o problema de busy- wait.

API do sistema operacional (SO)

Disponível na API do S.O. Java não oferece semáforos

Dois tipos de semáforos

Binário

contador

8585
8585

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

SEMÁFORO BINÁRIO

Semáforo binário:

Valor inicial: verdadeiro Fila de processos em wait: vazia

Operações básicas

P()

V()

wait

signal (notify)

8686
8686

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

T1:thread
T1:thread
S:SemaforoBinario
S:SemaforoBinario

true

false

T2:thread
T2:thread

wait

P( )

V( )

Na seção

crítica

P( )

true

false

notify( )

V( )

Na seção

crítica

true

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

8787
8787

Semáforo binário

SEMÁFOROS

Semáforo contador:

Operações básicas

P()

V()

Valor inicial: valor inteiro = número de processos permitidos na SC

wait decrementa um contador signal (notify) incrementa contador

Ver código

8888
8888

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Semáforo contador T1:thread S:SemaforoContador T2:thread T3:thread 2 P( ) 1 P( ) 0 Na seção
Semáforo contador
T1:thread
S:SemaforoContador
T2:thread
T3:thread
2
P( )
1
P( )
0
Na seção
P( )
crítica
V( )
wait
1
notify( )
0
V( )
1
Há dois recursos, neste caso o
semáforo é inicializado com 2
8989
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Problema do Produtor-Consumidor

Solução utilizando semáforos

K=5

◊ Problema do Produtor-Consumidor Solução utilizando semáforos K=5 PRODUTOR CONSUMIDOR BUFFER COMPARTILHADO

PRODUTOR

PRODUTOR
CONSUMIDOR

CONSUMIDOR

BUFFER COMPARTILHADO

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

9090
9090

PRODUTOR-CONSUMIDOR

PRODUTOR-CONSUMIDOR

PRODUTOR-CONSUMIDOR Solução utilizando semáforos

entrada 4 3 2 5 1 0 TAM -1
entrada
4 3
2
5
1
0
TAM -1

saída

9191
9191

PRODUTOR-CONSUMIDOR

Problemas

Exclusão mútua no acesso ao buffer (ou o produtor ou o consumidor) Consumidor não deve buscar itens quando o buffer está vazio Produtor não pode produzir se buffer estiver cheio

SINCRONIZAÇÃO CONDICIONAL: Um processo aguarda que uma condição se torne verdadeira antes de continuar suas operações.

Exemplos:

Consumidor aguarda a existência de um item Produtor aguarda espaço no buffer para produzir

9292
9292

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

PRODUTOR-CONSUMIDOR

Exercício (solução utilizando semáforos)

Baixe o código fonte Faça o diagrama de sequência para o cenário seguinte:

O produtor produz um item (double) O consumidor consome. O consumidor tenta consumir um item que não existe.

Código fonte e .jar disponível em JAVARepositorio/JThreads/JProdutorConsumidorSemaforos

9393
9393

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

SEMÁFOROS

Outros problemas bem-conhecidos

Leitor-escritor em banco de dados Não acessam o BD concorrentemente

Leitor e escritor Dois escritores

Múltiplos leitores acessam concorrentemente

Filósofos

9494
9494

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

MONITOR LOCK

MONITOR: mais alto nível e mais fácil de utilizar que semáforo

Java só trabalha com monitores

Todo objeto em Java é um monitor

9595
9595

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

MONITOR LOCK

Quando uma thread executa um bloco de código sincronizado, ela fecha o acesso às demais. Outra thread que tentar acessar a seção crítica (o bloco de código) não conseguirá até que a primeira libere o acesso.

Em java, o bloqueio é feito no objeto e não no método.

Isto é útil quando duas ou mais threads devem atualizar a mesma área de mémória (atributo compartilhado).

9696
9696

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

EXEMPLO MONITOR LOCK T1:thread obj:Compartilhado T2:thread Lock livre método sincronizado( ) Lock ocupado Na
EXEMPLO MONITOR LOCK
T1:thread
obj:Compartilhado
T2:thread
Lock livre
método sincronizado( )
Lock ocupado
Na seção
método sincronizado( )
crítica
fim método
waiting
notify( )
Na seção
crítica
fim método
Lock livre
9797
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Exemplo em JAVA ◊ Problema das roletas e contador central /** * Contador é um
Exemplo em JAVA
◊ Problema das roletas e contador central
/**
* Contador é um objeto compartilhado pelas threads roleta 1 e roleta 2.
*/
class ContadorCentral {
protected int numPessoas=0;
/**
* O código que faz a atualização da variável numPessoas é uma seção crítica.
* Somente um processo (ou thread) pode executá-lo por vez. Para impedir que
* mais de uma thread atualize numPessoas, utiliza-se a palavra-chave
* synchronized.
**/
protected synchronized void somarNumPessoas(int n) throws InterruptedException
{
numPessoas += n;
}
}
Ao executar somarNumPessoas de uma certa instância de ContadorCentral o lock fica retido.
Qualquer outro método (se houvesse) da instância não poderia ser executado enquanto o
somarNumPessoas não terminasse (lock liberado).
JAVARepositorio\JThreads\JRaceConditionRoletasSol
9898
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Exemplo em JAVA: outra forma ◊ Problema das roletas e contador central (equivale ao anterior,
Exemplo em JAVA: outra forma
◊ Problema das roletas e contador central (equivale ao anterior, só
muda a sintaxe)
/**
* Contador é um objeto compartilhado pelas threads roleta 1 e roleta 2.
*/
class ContadorCentral {
protected int numPessoas=0;
/**
* O código que faz a atualização da variável numPessoas é uma seção crítica.
* Somente um processo (ou thread) pode executá-lo por vez. Para impedir que
* mais de uma thread atualize numPessoas, utiliza-se a palavra-chave
synchronized.
**/
protected void somarNumPessoas(int n) throws InterruptedException {
synchronized (this) {
numPessoas += n;
*
}
}
}
JAVARepositorio\JThreads\JRaceConditionRoletasSol
9999
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
SINTAXE PARA SYNCHRONIZED São construções equivalentes public synchronized void metodo() { …. …. …. }
SINTAXE PARA SYNCHRONIZED
São construções equivalentes
public synchronized void metodo() {
….
….
….
}
public void metodo() {
synchronized (this) {
….
….
….
}
}
Métodos estáticos podem ser
sincronizados – equivale
a um lock de classe
100100
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
◊ Semântica A thread deve obter o lock deste objeto para entrar na SC synchronized
◊ Semântica
A thread deve obter o
lock deste objeto para
entrar na SC
synchronized (object)
enterMonitor():
{
como
….
se obtém o lock
entra no monitor
se não aguarda;
uma
….
seção
….
crítica
exitMonitor():
libera o lock e
}
notifica processos
bloqueados

Lock é para objeto (não para o bloco de código ou método)

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

101101
101101

MONITOR LOCK: SEMÂNTICA

EXERCÍCIO

Baixar o programa JRaceConditionRoletas do repositório e corrigir o problema de condição de corrida na atualização do contador central utilizando bloco de código synchronized.

Código fonte disponível em JAVARepositorio/JThreads/JRaceConditionRoletas/

Idem para o programa que atualiza saldo da conta corrente

Código fonte disponível em JAVARepositorio/JThreads/JCompartMemObjetoCC/

FIM
FIM

Solução em RepositorioJAVA/JThreads/JRaceConditionRoletasSol

102102
102102

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

MONITOR LOCK: WAIT/NOTIFY

Há situações onde, duas threads devem executar de forma concorrente dois blocos de código sincronizados do mesmo objeto.

Mas foi dito que uma vez que uma thread pega o lock de um objeto ela só o libera ao final do método!!!

Foi uma meia verdade

;-)

103103
103103

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

MONITOR LOCK: WAIT/NOTIFY tira põe THREAD 1 THREAD 2 WAIT pedestal vazio Põe peça Notifica
MONITOR LOCK: WAIT/NOTIFY
tira
põe
THREAD 1
THREAD 2
WAIT pedestal vazio
Põe peça
Notifica que colocou
WAIT pedestal ≠ vazio
Tira peça
Notifica que tirou
Pedestal
Objeto compartilhado
104104
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
MONITOR LOCK: WAIT/NOTIFY class Pedestal { boolean livre = true; } class RoboProdutor implements Runnable
MONITOR LOCK: WAIT/NOTIFY
class Pedestal {
boolean livre = true;
}
class RoboProdutor implements Runnable {
Pedestal p;
RoboProdutor(Pedestal p) {
this.p = p;
class RoboConsumidor implements Runnable {
Pedestal p;
RoboConsumidor(Pedestal p) {
this.p = p;
}
}
public void run() {
while (true) {
synchronized (p) {
while (!p.livre) {
p.wait();
public void run() {
while (true) {
synchronized (p) {
while (p.livre) {
p.wait();
}
}
println("Peça colocada");
p.livre=false;
p.notifyAll();
println("Peça retirada");
p.livre=true;
p.notifyAll();
}
}
}
}
}
}
}
}
Catch e try foram omitidos
Wait libera o lock; Notify não libera o lock
JAVARepositorio\JThreads\JExemploWaitNotifyPedestal
105105
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Produtor:Runnable
Produtor:Runnable
p:Pedestal Lock synchronized(p) Lock Obtém o lock de p synchronized(p) p.livre = false Livre=false notifyAll(
p:Pedestal
Lock
synchronized(p)
Lock
Obtém o lock de p
synchronized(p)
p.livre = false
Livre=false
notifyAll( )
fim bloco sync: libera o lock
Lock
synchronized(p)
Lock
Obtém o lock de p
Lock
Obtém o lock
p.livre = true
Livre=true
Consumidor:Runnable
Consumidor:Runnable

Início do run()

“Peça Colocada”

Início do run()

waiting

wait p.livre

“Peça Retirada”

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

106106
106106

EXEMPLO MONITOR LOCK

pelo lock

EXERCÍCIO

Baixe o código fonte dos robôs e pedestal

Inclua mais um robô consumidor

Identifique na mensagem impressa qual robô consumidor que faz a retirada da peça

Verifique se o programa funciona corretamente.

http://www.dainf.ct.utfpr.edu.br/~tacla/JAVARepositorio/JThreads/JExemploWaitNotifyPedestal/

107107
107107

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

MONITOR LOCK: WAIT, NOTIFY ◊ Cada monitor tem uma fila de processos bloqueados ◊ 3
MONITOR LOCK: WAIT, NOTIFY
◊ Cada monitor tem uma fila de processos bloqueados
◊ 3 métodos especiais podem ser usados dentro do monitor
synchronized
(object) {
Thread Libera o lock do object e
passa ao estado waiting
….
object.wait();
….
object.notify();
Se a fila não estiver vazia, pega um
processo qualquer da fila e o
desbloqueia
….
object.notifyAll(
);
….
}
Se a fila não estiver vazia,
desbloqueia todos os processos da
fila que vão disputar o lock – mas só
um será escolhido pelo escalonador
(ineficiente se houver muitas threads)
108108
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

NOTIFY x NOTIFY ALL

Utilizar notify no lugar de notify all somente quando as duas condições abaixo forem verdadeiras:

1. Threads em waiting possuem mesma condição de espera (ex. estahVazio). Todas as threads executam a mesma lógica quando saem do wait.

2. One-in, one-out. A notificação sobre a variável utilizada na condição habilita somente uma thread a prosseguir.

Fonte: Goetz, B. Java Concurrency in Practice, ed. Pearson Education, 2006, seção 14.2.4

109109
109109

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Exemplo típico synchronized(obj) { while(<condição>) { try { wait(); }catch (InterruptedException e) { }
Exemplo típico
synchronized(obj) {
while(<condição>)
{
try {
wait();
}catch (InterruptedException e) { }
}
// alguma coisa
notifyAll();
}
110110
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Métodosde bloco de código sincronizado

Usar somente em blocos de código sincronizado (caso contrário, erro de execução IllegalMonitorStateException)

Object.wait( ) libera o lock

Object.wait(<t em ms>) libera o lock

Object.notify()

Object.notifyAll()

Importante: não manipulam lock

Thread.yield() não libera o lock Thread.sleep(<t em ms>) não libera o lock Thread.suspend() não utilizar – deprecated Thread.resume() não utilizar - deprecated

deprecated Thread.resume() não utilizar - deprecated 111111 Programação Paralela e Distribuída -
111111
111111

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Tipos de monitores

Há duas implementações clássicas de monitores

Hoare: o processo que faz a notificação é interrompido

Estilo Java: o processo que faz a notificação não é necessariamente interrompido

112112
112112

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Dois tipos de monitores Processo 0 Processo 1 synchronized (object) { …. object.wait(); synchronized (object)
Dois tipos de monitores
Processo 0
Processo 1
synchronized (object) {
….
object.wait();
synchronized (object) {
….
object.notify();
Qual processo continua a execução nesse ponto?
….
….
}
}
Somente um processo pode estar no monitor: 2 possibilidades
113113
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
TIPO 1: MONITOR DE HOARE Process 0 Process 1 synchronized (object) { …. object.wait(); synchronized
TIPO 1: MONITOR DE HOARE
Process 0
Process 1
synchronized (object) {
….
object.wait();
synchronized (object) {
….
object.notify();
….
}
….
}
Processo 0 assume a execução
assim que o 1 faz notify
114114
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Tipo 1: MONITOR DE HOARE Process 0 Process 1 synchronized (object) { if (x !=
Tipo 1: MONITOR DE HOARE
Process 0
Process 1
synchronized (object) {
if (x != 1)
object.wait();
A
condição de sincronização
synchronized (object) {
(x=1) é seguramente verda-
deira quando o processo
x=1;
O
processo que notifica
object.notify();
é
notificado
é
interrompido
assert(x==1); // x é igual a 1
x++;
}
// x pode ser ≠≠≠≠ 0 neste ponto
}
No monitor HOARE, é possível fazer
condição sincronizada com if
115115
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
TIPO 2: MONITOR ESTILO JAVA Process 0 Process 1 synchronized (object) { …. object.wait(); synchronized
TIPO 2: MONITOR ESTILO JAVA
Process 0
Process 1
synchronized (object) {
….
object.wait();
synchronized (object) {
….
object.notify();
// código
// código
}
….
}
No monitor estilo Java, o Processo 1 continua
a executar após o notify
116116
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Tipo 2: MONITOR JAVA Process 0 Process 1 synchronized (object) { if (x != 1)
Tipo 2: MONITOR JAVA
Process 0
Process 1
synchronized (object) {
if (x != 1)
object.wait();
synchronized (object) {
x=1;
P0 realiza operações
assumindo x=1, sendo
que x pode ter outro
object.notify();
assert(x == 1); // x must be 1
x++;
valor
}
assert(x==1); // falso
x++;
}
Processo 1 continua a executar e pode modificar o valor de x. A
sincronização condicional com um simples if pode não funcionar.
117117
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla
Tipo 2: MONITOR JAVA Process 0 Process 1 synchronized (object) { while (x != 1)
Tipo 2: MONITOR JAVA
Process 0
Process 1
synchronized (object) {
while (x != 1)
object.wait();
Só sai do while
quando x=1
synchronized (object) {
x=1;
P0 realiza operações
assumindo x=1, sendo
que x será igual a 1
object.notify();
assert(x == 1); // x must be 1
x++
}
assert(x==1); // verdadeiro
x++;
}
Para solucionar o problema do slide anterior, é preciso colocar um
while (também resolve o caso de interrupções espúrias).
118118
Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Dois tipos de monitores

O monitor Java é mais usual

Porém, é prudente verificar o tipo de monitor quando for utilizar outra linguagem

Código de sincronização é extremamente difícil de debugar

Muitos bugs ficam escondidos durante anos sem que ninguém perceba Faça certo da primeira vez!

119119
119119

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

Resumo

Por que necessitamos de primitivas de sincronização?

Busy waiting desperdiça ciclos de CPU Primitivas de sincronização necessitam suporte do SO

Semáforo:

Binário, contador Produtor-consumidor

Monitor:

Mais fácil e mais popular que semáforos Dois tipos: Hoare e estilo Java

120120
120120

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla

EXERCÍCIO

EXERCÍCIO ◊ Problema do barbeiro dorminhoco Um barbeiro corta o cabelo de qualquer cliente. Se não

Problema do barbeiro dorminhoco

Um barbeiro corta o cabelo de qualquer cliente. Se não há clientes, o barbeiro tira uma soneca. Há várias threads, uma para cada cliente. Um cliente aguarda pelo barbeiro se há ao menos uma cadeira vazia na barbearia, Caso contrário, o cliente sai da barbearia imediatamente. Se há uma cadeira disponível, então o cliente senta. Se o barbeiro está dormindo, então o cliente acorda-o. Existem <n> cadeiras na barbearia.

Faça um programa para a classe BarbeiroDorminhoco utilizando monitor

121121
121121

Programação Paralela e Distribuída - Fundamentos/UTFPR Prof. Cesar Augusto Tacla