Este documento apresenta os conceitos fundamentais da programação concorrente. Em três frases:
A programação concorrente permite a execução simultânea de várias tarefas computacionais através de múltiplos fluxos de execução. Ela é útil para aproveitar recursos computacionais paralelos e tornar aplicações mais responsivas. No entanto, a concorrência também introduz riscos como corridas, deadlocks e inanição que devem ser evitados.
Slides Lição 6, CPAD, As Nossas Armas Espirituais, 2Tr24.pptx
Programação Concorrente - Introdução
1. UNIVERSIDADE ESTADUAL DO SUDOESTE DA BAHIA
CURSO DE CIÊNCIA DA COMPUTAÇÃO
PROGRAMAÇÃO CONCORRENTE – 2015.1
Fábio M. Pereira
(fabio.mpereira@uesb.edu.br)
2. Programação Concorrente
• Do inglês Concurrent Programming, onde Concurrent
significa “acontecendo ao mesmo tempo”
• É um paradigma de programação para a construção
de programas de computador que fazem uso da execução
concorrente (simultânea) de várias tarefas
computacionais interativas, que podem ser
implementadas como programas separados ou como um
conjunto de threads criadas por um único programa
• É diferente de computação paralela!
Fio, linha, fluxo
3. Programação Concorrente
• A programação concorrente foi usada inicialmente na
construção de sistemas operacionais
• Atualmente, ela é usada para desenvolver aplicações em
todas as áreas da computação
• Este tipo de programação tornou-se ainda mais
importante com o advento dos sistemas distribuídos e
das máquinas com arquitetura paralela
4. Programação Concorrente
• Tradicionalmente, a grande maioria dos programas
escritos são programas sequenciais
– Para serem executados em um único computador com uma
única CPU
– O problema é dividido em uma série de instruções que são
executadas uma após a outra
– Uma única instrução pode ser executada em um determinado
instante de tempo
• Nesse caso, existe somente um fluxo de controle (fluxo
de execução, linha de execução, thread) no programa
• Isso permite, por exemplo, que o programador realize
uma "execução imaginária" de seu programa apontando
com o dedo, a cada instante, o comando que está sendo
executado no momento
5. Programação Concorrente
• Um programa concorrente pode ser visto como se tivesse
vários fluxos de execução
– Para o programador realizar agora uma "execução imaginaria",
ele vai necessitar de vários dedos, um para cada fluxo de
controle
– Em programação concorrente é definido o uso simultâneo de
múltiplos recursos computacionais para resolver um problema
• Para ser executado em diversas CPUs:
– O problema é quebrado em partes que podem ser executadas
(resolvidas) concorrentemente
– Cada uma destas partes é representada por uma série de
instruções, sendo que as instruções de cada parte são
executadas concorrentemente em diferentes CPUs
6. Programação Concorrente
• É comum em sistemas multiusuário que um mesmo programa
seja executado simultaneamente por vários usuários:
– Por exemplo, um editor de texto
– Entretanto, ter 10 execuções simultâneas do editor de texto não faz
dele um programa concorrente – o que se tem são 10 processos
independentes executando o mesmo programa sequencial
(compartilhando o mesmo código)
– Cada processo tem a sua área de dados e ignora a existência das
outras execuções do programa
– Esses processos não interagem entre si (não trocam informações)
– Neste caso, é usado o termo programação paralela, pois vários
programas/processos independentes são executados em paralelo
pelo computador
• Um programa é considerado concorrente quando ele (o
próprio programa, durante a sua execução) origina diferentes
processos que irão interagir entre si para realizar alguma
tarefa
7. 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
8. Recursos Computacionais
• Um único computador com múltiplos processadores
• Um número arbitrário de computadores conectados pela
rede
• Uma combinação de ambos (múltiplos computadores,
com múltiplos processadores, conectados pela rede)
9. Problema Computacional
• O problema computacional geralmente demonstra
características como a habilidade de ser:
– Quebrados em partes de um trabalho que pode ser resolvido de
forma simultânea
– Executar múltiplas instruções do programa a qualquer
momento no tempo
– Resolvido em menos tempo com vários recursos de computação
do que com um único recurso computacional
10. Motivação
• Programação concorrente é mais complexa do que a
programação sequencial:
– Erros dos programas sequenciais + erros associados as
interações entre os processos
– Erros dependem do momento exato em que o escalonador do
SO realiza um chaveamento de contexto ou do recebimento de
uma mensagem
– Difícil reprodução e identificação
11. Motivação
• Apesar da maior complexidade, existem muitas áreas nas
quais a programação concorrente é vantajosa:
– Em sistemas nos quais existem vários processadores (máquinas
paralelas ou sistemas distribuídos), é possível aproveitar esse
paralelismo e acelerar a execução do programa
– Mesmo em sistemas com um único processador, existem razões
para o seu uso em vários tipos de aplicações
12. Exemplo
• Leitura, formatação e impressão de arquivo!
• Solução sequencial:
• Solução concorrente:
Arquivo
Impressora
FísicaProcesso
Arquivo
Processo
Leitor
Buffer
Processo
Impressor
Impressora
Física
13. Exemplo
• O uso da programação concorrente é natural nas
aplicações que apresentam paralelismo intrínseco, ditas
aplicações inerentemente paralelas
– Nessas aplicações pode-se distinguir facilmente funções para
serem realizadas em paralelo
– Este é o caso do spooling de impressão, exemplo que será
apresentado a seguir
• Pode-se dizer que, em geral, a programação concorrente
tem aplicação natural na construção de sistemas que
tenham de implementar serviços que são requisitados de
forma imprevisível
– Nesse caso, o programa concorrente terá um processo para
realizar cada tipo de serviço
14. Spooling de Impressão
• A seguir é considerado um servidor de impressão para
uma rede local
• A figura ilustra uma rede local na qual existem diversos
computadores pessoais (PC) utilizados pelos usuários e
existe um computador dedicado ao papel de servidor de
impressão
• O servidor usa um disco magnético para manter os
arquivos que estão na fila de impressão
Rede local incluindo um servidor de impressão dedicado
Usuários Servidor de Impressão
15. Spooling de Impressão
• É importante observar que o programa "servidor de
impressão" possui paralelismo intrínseco
• Ele deve:
1. receber mensagens pela rede
2. escrever em disco os pedaços de arquivos recebidos
3. enviar mensagens pela rede (contendo, por exemplo, respostas às
consultas sobre o seu estado)
4. ler arquivos previamente recebidos (para imprimí-los)
5. enviar dados para a impressora
• Todas essas atividades podem ser realizadas
simultaneamente
• Uma forma de programar o servidor de impressão é usar
vários processos, cada um responsável por uma atividade
em particular
– Obviamente, esses processos vão precisar trocar informações para
realizar o seu trabalho
17. Vantagens
• Economizar tempo e dinheiro
• Resolver grandes problemas
– Muitos problemas são tão grandes/complexos que é
impraticável ou impossível resolvê-los num único computador,
especialmente quando a memória é limitada
• Superar as limitações da computação sequencial:
– razões físicas e práticas restringem a construção de
computadores cada vez mais rápidos
• Arquiteturas de computadores atuais são cada vez mais
dependentes do paralelismo em nível de hardware para
melhorar o desempenho
18. Aplicações Mais Ágeis (responsive)
• Quando iniciamos uma aplicação, o fluxo principal de
execução, muitas vezes assume múltiplas
responsabilidades sequencialmente, dependendo das
ações que pedimos para realizar:
– Receber entrada de um usuário, ler um arquivo, executar alguns
cálculos, acessar um serviço web, atualizar um banco de dados,
exibir uma resposta ao usuário, e assim por diante
• Se cada uma dessas operações leva apenas frações de
segundo, então pode não haver necessidade real para
introduzir fluxos adicionais de execução
– Um único fluxo pode ser adequado para atender às
necessidades
19. Aplicações Mais Ágeis (responsive)
• Em aplicações não triviais, no entanto, essas operações
podem não ser tão rápidas:
– Cálculos podem levar de alguns segundos até alguns minutos
– Os pedidos de dados a um serviço web pode encontrar atrasos de
rede, de modo que o fluxo deve aguardar a resposta para chegar
– Enquanto isso está acontecendo, não há nenhuma maneira dos
usuários do aplicativo interagirem com, ou interromperem a
aplicação, porque um único fluxo é executado até que a operação
termine
• Concorrência pode não só ajudar a tornar as aplicações mais
ágeis, como também podem ajudar a melhorar a experiência
do usuário
– Os aplicativos podem olhar para frente em operações que o usuário
poderá realizar no próximo passo e realizar as ações necessárias,
como indexação ou cache de alguns dados de que o usuário precisa
20. Serviços
• Supondo que estamos encarregados de construir um
aplicativo que precisa processar lotes de notas fiscais de
vários fornecedores
• Isso exige que nós apliquemos regras e fluxo de trabalho
em cada fatura, mas podemos processá-las em qualquer
ordem
• O processamento dessas faturas sequencialmente não vai
aproveitar a taxa de transferência ou utilizar os recursos
disponíveis
• Nossa aplicação precisa processar essas faturas
simultaneamente
21. Vantagens
• Utilizar mais de um computador ou um computador com
mais de um processador, para resolver um determinado
problema
– N computadores operando simultaneamente podem atingir o
resultado N vezes mais rápido (não será exatamente N vezes
mais rápidos por uma série de razões)
• Outros motivos incluem:
– Tolerância a falhas, grande quantidade de memória disponível,
redução da latência, etc.
22. Perigos da Concorrência
• Agora, você provavelmente está pensando: "Eu posso ter
melhor rendimento, quebrando o meu problema e deixando
vários fluxos trabalharem sobre estas partes“
• Infelizmente, os problemas raramente pode ser dividido em
partes isoladas que podem ser executados totalmente
independentes umas das outras
– Muitas vezes, podemos executar algumas operações de forma
independente, mas depois temos que mesclar os resultados parciais
para obter o resultado final
• Isso requer que os fluxos comuniquem os resultados parciais
e às vezes esperar por esses resultados para finalizar o
trabalho
• Devemos possuir então, uma coordenação entre fluxos que
pode levar a problemas de sincronização e bloqueio
(deadlock)
23. Perigos da Concorrência
• Starvation (inanição)
– Ocorre inanição quando um processo nunca é executado
("morre de fome"), pois processos de prioridade maior sempre
o impedem de ser executado
24. Perigos da Concorrência
• Deadlock (interbloqueio, blocagem, impasse)
– No contexto de sistemas operacionais, caracteriza uma situação
em que ocorre um impasse e dois ou mais processos ficam
impedidos de continuar suas execuções, ou seja, ficam
bloqueados
– Trata-se de um problema bastante estudado no contexto dos
sistemas operacionais, assim como em outras disciplinas,
como banco de dados, pois é inerente à própria natureza desses
sistemas
– O deadlock ocorre quando um ou mais processos está
aguardando a liberação de um recurso por um outro processo
que, por sua vez, aguarda a liberação de outro recurso alocado
ou dependente do primeiro processo
25. Perigos da Concorrência
• Condições de corrida (race conditions)
– Se duas threads competem para usar o mesmo recurso ou
dados, temos uma condição de corrida
– A condição de corrida não acontecerão apenas quando dois
fluxos modificam dados, também pode acontecer mesmo
quando um está modificando dados, enquanto o outro está
tentando acessá-lo
– Condições de corrida pode tornar o comportamento de um
programa imprevisível, produzir execução incorreta, e produzir
resultados incorretos
26. Referências
• Wikipedia. Programação Concorrente. Acessado em:
fev/2015. Disponível em: http://pt.wikipedia.org/wiki/
Programação_concorrente
• ALCHIERI, E. Programação Concorrente: Introdução. UNB.
Acessado em: fev/2015. Disponível em:
www.cic.unb.br/~alchieri/disciplinas/graduacao/pc/intro
ducao.pdf
• TOSCANI, S. Programação Concorrente. PUCRS. Acessado
em fev/2015. Disponível em: www.inf.pucrs.br/~ramos/
sop_progconctext.doc
• SUBRAMANIAM, V. Programming Concurrency on the
JVM. The Pragmatic Bookshelf, 2011.
27. UNIVERSIDADE ESTADUAL DO SUDOESTE DA BAHIA
CURSO DE CIÊNCIA DA COMPUTAÇÃO
PROGRAMAÇÃO CONCORRENTE – 2015.1
Fábio M. Pereira
(fabio.mpereira@uesb.edu.br)