Programação Concorrente
Aula 01
Prof: André Luis Meneses Silva
Conteúdo
•
•
•
•
•
•
•
•
O que é
Motivação
Conceitos
Processos
Threads
Propriedades
Safety
Liveness
Programação Concorrente
[ O que é ]
• “Um programa concorrente é um conjunto de
programas seqüenciais comuns que são
executados em um paralelismo abstrato”
(M.Bem-Ari)
Programação Concorrente
[ O que é ]
• “Um programa concorrente especifica 2 ou
mais processos que cooperam para realizar
uma tarefa. Processos cooperam através de
comunicação; utilizam variáveis
compartilhadas ou troca de mensagens“(G. R.
Andrews)
Programação Concorrente
[ Motivação ]
• Aproveitar
hardware
com
múltiplos
processadores
• Atender a vários usuários simultaneamente
• Melhorar o desempenho das aplicações
• Aumentar a disponibilidade para o usuário
• Objetos ativos e controle de atividades
• Programas paralelos
Programação Concorrente
[ Conceitos ]
• Paralelismo
– Processamento simultâneo físico
• Concorrência
– Processamento simultâneo lógico (aparente)
– Requer entrelaçamento (interleaving) de ações
• Processo
– Execução de um programa
• Programa Concorrente
– Vários processos que cooperam para a realização de uma tarefa
Programação Concorrente
[ Conceitos ]
• Comunicação
– Variáveis compartilhadas
– Passagem de mensagens
• Sincronização
– Exclusão mútua de seções críticas
– Sincronização por condição
• Estado de um programa concorrente
– Consiste dos valores das variáveis (explícitas e implícitas)
– A execução de um comando muda o estado
• Ações atômicas
– Transformação indivisível de estado
Programação Concorrente
[ Processos ]
• Um processo é um programa que está em algum estado
de execução
• Tem espaço de endereçamento próprio, que é mapeado
pelo S.O. para memória física
• Possui um fluxo de controle ou thread único
• Mantém um contador de programa (PC) que indica o
endereço da próxima instrução
• A MMU (Memory Management Unit) traduz os
endereços lógicos em endereços físicos, que
normalmente não são contíguos (Memória Virtual)
Programação Concorrente
[ Processos ]
• Espaço de Endereçamento Lógico
Pilha
Espaço de
Endereçamento
Lógico de um
Processo
Heap
Dados Globais
Instruções
Programação Concorrente
[ Processos ]
• Tabela de Processos
– Estado do processo
– Valores dos registradores
– Arquivos abertos
– Alocação de memória
– PID (Process ID)
– UID (User ID)
– GID (Owner’s Group ID)
Programação Concorrente
[ Processos ]
• Estados de um processo
– Executando (Running): Utilizando a CPU
– Executável ou Pronto (Runnable ou Ready):
Esperando para ser escalonado para usar a CPU
– Suspenso (Suspended): Recebeu um sinal para ser
suspenso
– Bloqueado (Blocked): Esperando pela conclusão
de algum serviço solicitado ao S.O.
Programação Concorrente
[ Processos ]
Ativo
Bloqueado
Executável
Executando
Encerrado
Iniciado
Suspenso
Programação Concorrente
[ Threads ]
• Um processo pode ter mais de uma Thread
(Linha)
• Cada Thread possui contador de programa e
pilha próprios
• Quando um processo é escalonado para ser
executado, uma das Threads entra em
execução
• As Threads compartilham as variáveis globais
do processo
Programação Concorrente
[ Threads ]
Espaço de Endereçamento de um Processo
Pilha
Thread 1
Thread 2
Thread n
Pilha
Pilha
Pilha
Contador
de Programa
Contador
de Programa
Contador
de Programa
Heap
Variáveis Globais
Instruções
Programação Concorrente
[ Threads ]
• Vantagens sobre processos compartilhando
memória
– São muito mais leves de serem criadas
– A troca de contexto é mais suave pois compartilha
instruções, heap e variáveis globais
– Facilitam o compartilhamento de memória
Threads
[ Ciclo de Vida ]
Intervalo de tempo expirou
sleep
Dormindo
Encerrada
escalonada
Criada
start
Término
Pronta
Executando
interrompida
Operação
de E/S
concluída
wait
notify
notityAll
Operação
de E/S
iniciada
Esperando
Bloqueada
Threads
[ Sincronização ]
• Sincronizando Threads
– Programação com múltiplas Threads requer
bastante cuidado:
•
•
•
•
Acesso / Atualização de variáveis compartilhadas
Starvation
Deadlock
Acesso a estados inválidos de outros objetos
Threads
[ Sincronização ]
• Problema de acesso a variáveis compartilhadas
– Várias Threads (representando os depósitos dos clientes)
querendo atualizar (depositar um valor) uma mesma conta
– Quando uma está lendo o saldo atual, uma outra Thread pode já
ter lido esse valor e calculado o novo saldo, mas ainda não ter
gravado o novo valor
– Se nesse momento a primeira Thread gravar o valor, o saldo
final será igual ao calculado pela Thread que gravar o novo valor
por último (desconsiderando assim o depósito da Thread que
encerrou primeiro).
– O ideal é impedir que uma operação de depósito seja iniciada
antes da outra encerrar
Threads
[ Sincronização ]
• A sincronização baseia-se na idéia de que para acessar
um método sincronizado ou um entrar em um bloco
sincronizado, é preciso obter (ou já ter) o lock desse
objeto.
• A Thread que conseguir esse lock é a única autorizada a
acessar os recursos protegidos através de sincronização.
Programação Concorrente
[ Propriedades ]
• Safety: O programa nunca entra em um estado
inconsistente)
• Liveness: Em algum momento o programa entra em um
estado consistente
• Correção Parcial: Se o programa terminar, o resultado
está correto. Caso contrário, nunca pode dar o resultado
correto
• Término: O programa termina eventualmente
• Ausência de Deadlock: Nunca todos os processos estarão
bloqueados
• Correção Total: O programa sempre termina e produz o
resultado correto
Safety
[ Introdução ]
• Objetos interagindo em múltiplas Threads
normalmente provocam interferência
• Programas concorrentes devem possuir 2
propriedades:
– Safety: Nada de mau acontecerá durante a
execução do programa.
– Liveness: Algo de bom acontecerá durante a
execução do programa.
Safety
[ Introdução ]
• Em geral há mais atenção sobre Safety na engenharia
– É melhor que o programa não faça nada a ter um
comportamento aleatório ou até perigoso
• Liveness está relacionada ao progresso do programa
• Em alguns casos é melhor obter uma informação
imprecisa a não receber
– Sistemas de Suporte a Decisão, Data Warehouse e Simulação de
Trânsito
• Melhorar a Liveness pode implicar em reduzir a Safety
Safety
[ Objetos Seguros ]
• Em programa OO, o controle de interferência
é implementado de classe a classe
• Objetos/variáveis
podem
entrar
temporariamente em um estado inconsistente
• Um objeto/variável é considerado seguro
quando:
– Seu estado consistente é sempre consistente
– Operações não são realizadas enquanto está em
um estado inconsistente
Safety
[ Objetos Seguros ]
• Há 3 estratégias conservadoras para projetar
objetos/variáveis seguros:
– Imutabilidade: evitar mudanças de estado
– Sincronização:
garantir
acesso
exclusivo
dinamicamente
– Contenção:
garantir
acesso
exclusivo
estruturalmente
Safety
[ Imutabilidade ]
• Variáveis de instância constantes (final em
Java)
• Encapsulamento
• Não requer sincronização
• Classes sem estado (stateless)
– Como não há estado, não há interferência
Safety
[ Sincronização ]
• Um Objeto/variável sempre está pronto para
sofrer modificações, mesmo quando ainda
está no meio do processamento de alguma
• Acesso a estados inconsistentes devem ser
evitados:
– Conflitos de leitura/escrita: vários lêem enquanto
um escreve
– Conflitos de escrita/escrita: vários lêem e
escrevem ao mesmo tempo
Safety
[ Sincronização ]
• No contexto de OO, podemos ter:
– Sincronização Total
• Objetos totalmente sincronizados. Podem fazer apenas
uma operações por vez
– Sincronização Parcial
• Parte do objeto é sincronizado. Somente métodos
sincronizados são travados
Safety
[ Contenção ]
• Baseia-se na idéia de manter referências únicas para
objetos internos isolados dos demais.
• São acessados apenas através de métodos sincronizados
do objeto no qual estão contidos, estando, portanto,
protegidos.
interno1
externo1
interno2
subinterno1
Safety
[ Contenção ]
• Recursos Exclusivos
– Garante que somente um objeto por vez é
“proprietário” do recurso exclusivo. Porém, a
propriedade de um recurso pode mudar
– Semelhanças com objetos físicos:
•
•
•
•
Se você tem um, então pode usá-lo
Se você tem um, ninguém mais pode tê-lo
Se você da um para alguém, então deixa de tê-lo
Se você destrói um, ninguém nunca mais o terá
Safety
[ Contenção ]
– É preciso definir um protocolo que garanta a
exclusividade do recurso
null
null
serviço 1
vizinho
vizinho
serviço 0
serviço 2
vizinho
vizinho
serviço 3
null
Recurso
Liveness
[ Introdução ]
• Projetos baseados em combinações de
Imutabilidade, Sincronização e Contenção são
abordagens simples, rápidas e de fácil
entendimento para o desenvolvimento de
programas concorrentes OO
• Porém, essas técnicas nem sempre são a
melhor solução
• Utilização de Sincronização pode provocar
problemas de Liveness (eficiência)
Liveness
[ Falhas de Liveness ]
• São tão sérias quanto falhas de Safety
• São mais difíceis de identificar e evitar durante
o projeto
• Tipos de falhas
– Contenção: uma thread, apesar de estar pronta
para executar, não executa porque outra tomou
recursos (também conhecida como starvation ou
adiamento infinito)
Liveness
[ Falhas de Liveness ]
– Dormência: uma thread não pronta falha ao
tentar passar para esse estado.
– Deadlock: duas ou mais threads bloqueiam-se em
um ciclo vicioso enquanto tentam acessar travas
sincronizadas necessárias para continuar suas
atividades
– Término prematuro: uma thread é parada ou
encerrada prematuramente
Liveness
[ Análise de Variáveis de Instância ]
• Através de análise de variáveis e métodos, é
possível identificar oportunidades para reduzir
a sincronização
• Muitas vezes, a proteção implementada é
exagerada
Liveness
[ Análise de Variáveis de Instância ]
• Acesso
– Métodos de acesso podem deixar de ser
sincronizados para permitir leitura durante a
escrita
– Condições para remover a sincronização:
• A variável não pode assumir valores ilegais durante a
execução dos métodos
• Atribuição atômica
Liveness
[ Análise de Variáveis de Instância ]
• Atualização
– Métodos de atualização podem abdicar da
sincronização quando satisfaz, além das condições
para acesso:
• Valor da variável permanece consistente em todas as
possíveis situações (Ex: atributo temperatura sendo
atualizado constantemente por múltiplas threads)
• Não requer ações especiais sincronizadas para certos
valores assumidos pelas variáveis (Ex: reconstruir uma
estrutura de dados após atingir um tamanho)
Referências
• Concurrent Programming - Hartley (capítulo 1)
• Concurrent Programming in Java - Lea
(capítulo 1, 2 e 3)
Download

Programação Concorrente – Aula 01