Programação concorrente

6
Disciplina: Sistemas Operacionais Professor: Arildo Antônio Sônego Acadêmicos: Fábio Duarte de Souza Mateus Luiz Título: Linguagens de Programação Concorrente Programação Concorrente Programação concorrente é uma visão que o programador possui sobre a estruturação e execução de um programa. Por exemplo, em programação orientada a objetos, programadores podem abstrair um programa como uma coleção de objetos que interagem entre si, enquanto em programação funcional os programadores abstraem o programa como uma sequência de funções executadas de modo empilhado. Para a construção de programas e execução concorrente (simultânea) de várias tarefas computacionais interativas, que podem ser implementadas como programas separados ou como um conjunto de thread criadas por um único programa. Essas tarefas também podem ser executadas por um único processador, vários processadores em um único equipamento ou processadores distribuídos por uma rede. Programação concorrente é relacionada com programação paralela, mas foca mais na interação entre as tarefas. A interação e a comunicação correta entre as diferentes tarefas, além da coordenação do acesso concorrente aos recurso computacionais são as principais questões discutidas durante o desenvolvimento de sistemas concorrentes. Pioneiros na área de programação concorrente incluem Edsger Dijkstra, Per Brinch Hansen, e C. A. R. Hoare. Interação e comunicação concorrente Em alguns sistemas computacionais concorrentes, a comunicação entre os componentes é escondida do programador, enquanto em outros a comunicação deve ser lidada explicitamente. A comunicação explícita pode ser dividida em duas classes: Comunicação por memória compartilhada Componentes concorrentes comunicam-se ao alterar o conteúdo de áreas de memória compartilhadas. Java e C# são linguagens que utilizam tal modelo. Esse estilo de programação geralmente requer o

Transcript of Programação concorrente

Page 1: Programação concorrente

Disciplina: Sistemas OperacionaisProfessor: Arildo Antônio SônegoAcadêmicos: Fábio Duarte de Souza

Mateus LuizTítulo: Linguagens de Programação Concorrente

Programação Concorrente

Programação concorrente é uma visão que o programador possui sobre a estruturação e execução de um programa. Por exemplo, em programação orientada a objetos, programadores podem abstrair um programa como uma coleção de objetos que interagem entre si, enquanto em programação funcional os programadores abstraem o programa como uma sequência de funções executadas de modo empilhado.

Para a construção de programas e execução concorrente (simultânea) de várias tarefas computacionais interativas, que podem ser implementadas como programas separados ou como um conjunto de thread criadas por um único programa.

Essas tarefas também podem ser executadas por um único processador, vários processadores em um único equipamento ou processadores distribuídos por uma rede.

Programação concorrente é relacionada com programação paralela, mas foca mais na interação entre as tarefas. A interação e a comunicação correta entre as diferentes tarefas, além da coordenação do acesso concorrente aos recurso computacionais são as principais questões discutidas durante o desenvolvimento de sistemas concorrentes. Pioneiros na área de programação concorrente incluem Edsger Dijkstra, Per Brinch Hansen, e C. A. R. Hoare.

Interação e comunicação concorrente

Em alguns sistemas computacionais concorrentes, a comunicação entre os componentes é escondida do programador, enquanto em outros a comunicação deve ser lidada explicitamente. A comunicação explícita pode ser dividida em duas classes:

Comunicação por memória compartilhada

Componentes concorrentes comunicam-se ao alterar o conteúdo de áreas de memória compartilhadas. Java e C# são linguagens que utilizam tal modelo. Esse estilo de programação geralmente requer o desenvolvimento de alguns métodos de trava como mutex, semáforo ou monitor para gerenciar a utilização da memória entre as tarefas.

Comunicação por troca de mensagens

Componentes concorrentes comunicam-se ao trocar mensagens. Erlang e Occam são linguagens que utilizam tal modelo. A troca de mensagens pode ser lidada assincronamente (também denominada como "enviar e rezar", apesar da prática padrão ser reenviar mensagens que não são sinalizadas como recebidas) ou pelo método rendezvous, no qual o emissor é bloqueado até que a mensagem seja recebida.

A comunicação por mensagens tende a ser mais simples que a comunicação por memória compartilhada, e é considerada como uma forma mais robusta de programação concorrente.

Coordenando o acesso aos recursos

Page 2: Programação concorrente

Um dos assuntos de maior discussão em programação concorrente é como prevenir que tarefas concorrentes interfiram umas nas outras. Por exemplo, considerando o seguinte algoritmo para realizar saques de uma conta representada pelo recurso compartilhado balanco:

1 bool saque(int quantia) {2 if( balanco > quantia ) {3 balanco = balanco - quantia;4 return true;5 } else return false;6 }

Suponha que balanco = 500, e dois processos concorrentes realizam a chamada saque(300) e saque(350) . Se em ambas as operações a linha 2 é executada antes da linha 3 do processo concorrente, ambas as operações irão deduzir que o balanço é maior que a quantia a ser sacada, e a execução irá proceder subtraido os valores a serem sacados em ambos os processos. Apesar disso, como ambos os processos realizam o saque, o balanço acaba ficando com valor negativo, um resultado que não deveria acontecer. Esses tipos de probemas com recursos compartilhados requerem o uso de controles concorrentes, ou algoritmos não bloqueantes.

Como sistemas concorrentes necessitam a utilização de recursos compartilhados, a programação concorrente geralmente requer o uso de algum método de árbitro, um elemento neutro, para coordenar o acesso a tais recursos. Isso introduz a possibilidade do aparecimento de problemas com decisões não determinísticas, apesar de que o desenvolvimento cuidadoso de árbitros pode reduzir a probabilidade de tais situações aparecerem.

Linguagens para programação concorrente

As linguagens de programação concorrente são linguagens de programação que usam construções para a concorrência. Tais construções podem envolver multi-tarefa, suporte para sistemas distribuídos, troca de mensagens e recursos compartilhados.

Atualmente, as linguagens mais utilizadas para tais construções são Java e C#. Ambas utilizam o modelo de memória compartilhada, com o bloqueio sendo fornecido por monitores. Apesar disso, o modelo de troca de mensagens pode ser implementado sobre o modelo de memória compartilhada. Entre linguagens que utilizam o modelo de troca de mensagens, Erlang é possivelmente a mais utilizada pela indústria atualmente.

Várias linguagens de programação concorrente foram desenvolvidas como objeto de pesquisa, como por exemplo Pict. Apesar disso, linguagens como Erlang, Limbo e Occam tiveram uso industrial em vários momentos desde a década de 1980.

Várias outras linguagens oferecem o suporte à concorrência através de bibliotecas, como por exemplo C e C++.

Linguagem de Programação Limbo

É uma linguagem de programação que foi desenvolvida pela Lucent Technologies Inc. para a execução de aplicações distribuídas de pouca escalabilidade (aplicações que executam sobre um número pequeno de nodos).

Limbo é uma linguagem de programação imperativa , que apesar de rodar em cima de uma máquina virtual, não é considerada orientada a objetos, pois não possui suporte a herança e nem a definição de classes .

Byte unsigned (8-bits)int signed (32-bits)

Page 3: Programação concorrente

big signed (64-bits)real long float (64-bits)list,arrayStringchannel (para comunicaçao entre processos)adt (análogo ao struct presente em C)pick (análogo ao union presente em C)module

Exemplo de código da Linguagem Limbo:

hello.b)implement Hello;include "sys.m"; //biblioteca da linguagem Limbosys: Sys;include "draw.m";Hello: module{init: fn(ctxt: ref Draw->Context, argv: list of string);};init(ctxt: ref Draw->Context, argv: list of string){sys = load Sys Sys->PATH;sys->print("hello, world\n");}

OCCAM

OCCAM é uma linguagem para aplicações científicas e de engenharia, para processos de controle industrial e para sistemas embarcados. OCCAM foi originalmente projetado para transputer (contração entre transistor e computer), uma arquitetura microprocessada, desenvolvida pelo INMOS, que suporta concorrência e sincronização.

A OCCAM possui características especiais para solução de problemas de programação concorrente (cf. CARNEIRO, 2001, p.35) e a semântica formal da linguagem auxilia a transformação e validação dos programas em modelos matemáticos.

Em OCCAM, as partes de um programa são tomadas como processos que executam suas funções e terminam. Pode-se ter mais de um processo sendo executado concorrentemente e processos podem trocar mensagens entre si (cf. CARNEIRO, 2001, p.35).

A comunicação é feita através de um construtor especial da linguagem chamado canal. Um canal é um caminho unidirecional de comunicação entre dois processos concorrentes e é implementado na prática usando regiões alocadas de memória, se os processos estão residentes no mesmo transputer, ou por links de comunicação dos transputers, se os processos comunicantes estiverem em diferentes transputers.

P1 P2 SEQ SEQ

canal1 ! A canal2 ! Xcanal2 ? B canal1 ? X

PAR

Page 4: Programação concorrente

SEQcanal3 ? valor1valor := valor1 + 1

SEQcanal4 ! valor2valor2 := valor2 + 1

Linguagem de programação Erlang

Erlang é uma linguagem de programação declarativa, para programação paralela e distribuída. Seu “jeitão” é muito mais parecido com Prolog ou Lisp que com C ou Java… e não é orientada a objetos, é “orientado à concorrência”, como costuma-se dizer.

Tanto a AMD quanto a Intel estão criando processadores dual core e quad core para as massas. A Intel também tem o Hyper-Threading, que trata um núcleo como se fossem dois. Um processador Intel Xeon quad core com HT comporta-se como se fossem 8 processadores! Atualmente temos o Pentium Itanium, Pentium Xeon, Pentium 4 HT e AMD Opteron que podem ser utilizados de forma paralela (ambos os núcleos trabalhando ao mesmo tempo).

O bacana do Erlang é que ela tira o máximo proveito de paralelismo com processadores. Na teoria, um programa em Erlang é N vezes mais rápido que um programa em outras linguagens sem paralelismo, sendo N o número de processadores na máquina. Na teoria pois nem sempre o processador é o gargalo da performance, pode ser leitura/escrita em disco, acesso à memória, interface com outros dispositivos, sistema operacional, etc.

Código escrito em Erlang

-module(hello_concurrent).

-export([receiver/0. giver/1. start/0]).

receiver() ->receive diediedie -> ok; { name, Name} -> io:format(“hello, ~s~n”, [Name]), receiver() end.

giver(ReceiverPid) -> ReceiverPid = spawn(hello_concurrent, receiver, [] ), spawn(hello_concurrent, giver, [ReceiverPid]), start_finished.