concorrência e paralelismo - puc-rioinf1621/concorrencia.pdf · programação concorrente e...

25
Linguagens de Programacão I [email protected] 1 Concorrência e Paralelismo Concorrência e Paralelismo Linguagens de Programacão I [email protected] 2 Programação Concorrente Programação Concorrente e Paralela e Paralela Na programação sequencial todas as Na programação sequencial todas as instruções de um programa são instruções de um programa são executadas através de uma única linha executadas através de uma única linha de execução de execução Na programação concorrente e paralela Na programação concorrente e paralela um programa pode ser executado um programa pode ser executado através de diversas linhas de execução. através de diversas linhas de execução.

Upload: phungnguyet

Post on 20-Nov-2018

221 views

Category:

Documents


0 download

TRANSCRIPT

1

Linguagens de Programacão [email protected] 1

Concorrência e ParalelismoConcorrência e Paralelismo

Linguagens de Programacão [email protected] 2

Programação ConcorrenteProgramação Concorrentee Paralelae Paralela

Na programação sequencial todas as Na programação sequencial todas as instruções de um programa são instruções de um programa são executadas através de uma única linha executadas através de uma única linha de execuçãode execução

Na programação concorrente e paralela Na programação concorrente e paralela um programa pode ser executado um programa pode ser executado através de diversas linhas de execução.através de diversas linhas de execução.

2

Linguagens de Programacão [email protected] 3

Programação ConcorrenteProgramação Concorrentee Paralelae Paralela

tarefa 1

tarefa 2

tarefa 3

tarefa 1 tarefa 2 tarefa 3

vários fluxos de execuçãofluxo único de execução

Linguagens de Programacão [email protected] 4

Programação ConcorrenteProgramação Concorrentee Paralelae Paralela

Os mecanismos para programação Os mecanismos para programação concorrente e paralela compreendem as concorrente e paralela compreendem as construções que LPs usam para:construções que LPs usam para:

indicar quais unidades são concorrentes;indicar quais unidades são concorrentes;

ativar e controlar o fluxo de execução de unidades ativar e controlar o fluxo de execução de unidades concorrentes;concorrentes;

possibilitar a interação e sincronização entre possibilitar a interação e sincronização entre unidades concorrentes.unidades concorrentes.

3

Linguagens de Programacão [email protected] 5

Porque Usar Programação Porque Usar Programação Concorrente?Concorrente?

GanhosGanhos de de desempenhodesempenho emem sistemassistemas com com múltiplosmúltiplosprocessadoresprocessadores ((paralelismoparalelismo físicofísico). ).

GanhosGanhos de de desempenhodesempenho atravésatravés de de acessoacesso concorrenteconcorrente a a dispositivosdispositivos de hardware de hardware -- o o acessoacesso a discos a discos ouou a a dispositvosdispositvosde de rederede nãonão precisaprecisa bloquearbloquear todatoda a a aplicaçãoaplicação, , masmas apenasapenas um um thread.thread.

MaiorMaior responsividaderesponsividade dada aplicaçãoaplicação -- threads com threads com altaalta prioridadeprioridadepodempodem ser ser associadadosassociadados a a tarefastarefas críticascríticas (ex: (ex: vídeovídeo).).

MaiorMaior facilidadefacilidade emem capturarcapturar e e estruturarestruturar a a lógicalógica de de certascertasaplicaçõesaplicações ((aplicaçõesaplicações iterativasiterativas, , servidoresservidores, etc)., etc).

Linguagens de Programacão [email protected] 6

A

tempo

B

C

A

tempo

B

C

paralelismofísico

paralelismológico

3 processos3 processos3 processadores3 processadores

3 processos3 processos1 processador1 processador

Paralelismo Físico e LógicoParalelismo Físico e Lógico

4

Linguagens de Programacão [email protected] 7

ProcessosProcessos

Um processo é um fluxo de controle Um processo é um fluxo de controle sequencial e seu espaço de endereçamento sequencial e seu espaço de endereçamento (registradores, memória e arquivos). (registradores, memória e arquivos).

Informalmente um processo é a execução de Informalmente um processo é a execução de um programa junto com os dados usados por um programa junto com os dados usados por ele. ele.

A criação, execução e o encerramento de A criação, execução e o encerramento de processos são tratados diretamente pelo processos são tratados diretamente pelo sistema operacional.sistema operacional.

Linguagens de Programacão [email protected] 8

Estados de um ProcessosEstados de um Processos

executando

prontobloqueado

23

4

1

1.1. Processo é bloqueado Processo é bloqueado por operação de I/Opor operação de I/O

2.2. Escalonador escolhe Escalonador escolhe um novo processoum novo processo

3.3. Novo processo começa Novo processo começa a executara executar

4.4. Operação de I/O é Operação de I/O é completadacompletada

5

Linguagens de Programacão [email protected] 9

ThreadsThreads

Um processo tem duas partes: Um processo tem duas partes:

O fluxo de controle;O fluxo de controle;

O espaço de endereçamento (memória e outros recursos O espaço de endereçamento (memória e outros recursos como Icomo I\\O). O).

Um thread consiste somente no fluxo de controle e Um thread consiste somente no fluxo de controle e numa pilha de memória independente.numa pilha de memória independente.

O escalonamento de um thread é uma operação O escalonamento de um thread é uma operação mais simples, já que não envolve a mudança integral mais simples, já que não envolve a mudança integral do espaço de endereçamento.do espaço de endereçamento.

Linguagens de Programacão [email protected] 10

Criação de ProcessosCriação de ProcessosA criação de novos processos sempre é controlada A criação de novos processos sempre é controlada pelo SO pelo SO Um processo é uma abstração do SO.Um processo é uma abstração do SO.

Em Unix processos podem ser criados Em Unix processos podem ser criados explicitamente através do comandoexplicitamente através do comando forkfork():():pid = fork();pid = fork();if ( pid < 0 )if ( pid < 0 )

{ printf(``Cannot fork!!n'');{ printf(``Cannot fork!!n'');exit(1);exit(1);

}}if ( pid == 0 )if ( pid == 0 )

{ /* Child process */ ...... } { /* Child process */ ...... } elseelse

{ /* Parent process pid is child's pid */{ /* Parent process pid is child's pid */.... }.... }

6

Linguagens de Programacão [email protected] 11

Criação de ThreadsCriação de ThreadsO suporte a threads pode acontecer através da semântica O suporte a threads pode acontecer através da semântica básica da LP ou através de bibliotecas e pacotes específicos.básica da LP ou através de bibliotecas e pacotes específicos.

Alguns SOs oferecem suporte a threads (Windows XP, Linux) Alguns SOs oferecem suporte a threads (Windows XP, Linux) mas nem todos (diversas implementações de Unix). mas nem todos (diversas implementações de Unix).

Exemplos de LPs com suporte explícito a concorrência são Exemplos de LPs com suporte explícito a concorrência são Algol, Ada, Modula 3, Occam, Java e C#.Algol, Ada, Modula 3, Occam, Java e C#.

Exemplos de pacotes e bibliotecas para programação Exemplos de pacotes e bibliotecas para programação concorrente e paralela são PVM e MPI (Fortran, C/C++) e concorrente e paralela são PVM e MPI (Fortran, C/C++) e pthreads (C/C++).pthreads (C/C++).

Linguagens de Programacão [email protected] 12

Criação de ThreadsCriação de Threads

Os principais mecanismos de criação Os principais mecanismos de criação de threads são:de threads são:

CoCo--begin;begin;Loops paralelos;Loops paralelos;Instanciação na elaboração;Instanciação na elaboração;Instanciação explícita.Instanciação explícita.

7

Linguagens de Programacão [email protected] 13

CoCo--beginbegin

Blocos de código que podem ser executados Blocos de código que podem ser executados de forma concorrente são delimitados por de forma concorrente são delimitados por uma declaração especial (uma declaração especial (parpar).).

Em Algol temos:Em Algol temos:par begin # comandos neste bloco são concorrentes #par begin # comandos neste bloco são concorrentes #

p(a)p(a)begin # comandos neste bloco são sequenciais #begin # comandos neste bloco são sequenciais #

b: = x + y;b: = x + y;c:= f (b, d)c:= f (b, d)

endendp(f)p(f)

end end

Linguagens de Programacão [email protected] 14

Loops ParalelosLoops Paralelos

Em algumas LPs as iterações de um Em algumas LPs as iterações de um loop podem ser executadas de forma loop podem ser executadas de forma concorrente através de uma construção concorrente através de uma construção específica.específica.

Em Occam temos:Em Occam temos:

co (i:= 1 to 10) co (i:= 1 to 10) --> > f(a, b, i) # são criados 10 threads#f(a, b, i) # são criados 10 threads#

oc oc

8

Linguagens de Programacão [email protected] 15

Instanciação na ElaboraçãoInstanciação na Elaboração

Em Ada e SR o código de um thread pode ser Em Ada e SR o código de um thread pode ser definido de forma semelhante a uma subrotina. definido de forma semelhante a uma subrotina. Quando a subrotina é invocada, o thread é criado Quando a subrotina é invocada, o thread é criado automaticamente e começa a executar.automaticamente e começa a executar.

procedure P isprocedure P istask T istask T is

......end T;end T;

begin begin --–– corpo de Pcorpo de P......

end P; end P;

Linguagens de Programacão [email protected] 16

Instanciação ExplícitaInstanciação ExplícitaNormalmente bibliotecas e pacotes com suporte a Normalmente bibliotecas e pacotes com suporte a threads permitem apenas a criação explícita de threads permitem apenas a criação explícita de threads.threads.

Em pthreads um novo thread é criado explicitamente Em pthreads um novo thread é criado explicitamente através do comando através do comando pthread_createpthread_create() que recebe () que recebe como parâmetro a rotina a ser executada pelo novo como parâmetro a rotina a ser executada pelo novo thread.thread.

Em Java um thread é criado através da instanciação Em Java um thread é criado através da instanciação de um objeto de uma classe que representa um novo de um objeto de uma classe que representa um novo thread.thread.

9

Linguagens de Programacão [email protected] 17

Instanciação ExplícitaInstanciação Explícita

Exemplo C Exemplo C –– pthreads:pthreads:int main(int argc, char *argv[]) {int main(int argc, char *argv[]) {......for (i=0; i< n_workers; i++){for (i=0; i< n_workers; i++){

erro = pthread_create(&tid[i], NULL, worker,(void *) i); erro = pthread_create(&tid[i], NULL, worker,(void *) i); if (erro){if (erro){

printf("Erro na criacao do thread!!");printf("Erro na criacao do thread!!");exit(1);exit(1);

}}}}

void *worker(void *arg) {void *worker(void *arg) {int id = (int) arg;int id = (int) arg;printf("Sou o worker %dprintf("Sou o worker %d\\n",id);n",id);......

}}

Linguagens de Programacão [email protected] 18

SincronizacãoSincronizacão

Aplicações multiAplicações multi--threads precisam usar mecanismos threads precisam usar mecanismos específicos para controlar a iteração entre os específicos para controlar a iteração entre os diferentes threads. diferentes threads.

A sincronização entre threads pode ser feita através A sincronização entre threads pode ser feita através de dois mecanismos básicos: memória de dois mecanismos básicos: memória compartilhada e troca de mensagens.compartilhada e troca de mensagens.

Os dois principais mecanismos de sincronização com Os dois principais mecanismos de sincronização com memória compartilhada são semáforos e monitores.memória compartilhada são semáforos e monitores.

10

Linguagens de Programacão [email protected] 19

SemáforosSemáforos

Semáforos são estruturas de dados especiais Semáforos são estruturas de dados especiais que podem assumir apenas valores inteiros, que podem assumir apenas valores inteiros, sendo manipulados através das funções sendo manipulados através das funções PP ( ( ou ou downdown) e ) e VV ( ou ( ou upup).).

Para um semáforo s temos:Para um semáforo s temos:

P(s)P(s) sese s>0 s>0 entãoentão s= s s= s --1 1 senãosenão supender a execusupender a execuçção ão do thread correntedo thread corrente

V(s)V(s) sese existe algum thread suspenso existe algum thread suspenso entãoentão escolher escolher um qualquer e executum qualquer e executáá--lo lo senãosenão s=s+1s=s+1

Linguagens de Programacão [email protected] 20

MutexMutexMutex são semMutex são semááforos binforos bináários que podem assumir apenas os rios que podem assumir apenas os valores 0 e 1. valores 0 e 1.

SãoSão utilizados para permitir o acesso exclusivo a recursos ou utilizados para permitir o acesso exclusivo a recursos ou para definir regiões críticas do programa (trechos de código quepara definir regiões críticas do programa (trechos de código quenão podem ser executados concomitantemente):não podem ser executados concomitantemente):sem mutex = 1sem mutex = 1process CS [i=1 to n]{process CS [i=1 to n]{

while (true){while (true){P(mutex);P(mutex);região crítica;região crítica;V(mutex);V(mutex);região não críticaregião não crítica

}}}}

11

Linguagens de Programacão [email protected] 21

Problema do ProdutorProblema do Produtor\\ConsumidorConsumidor

produtores consumidoresbufferput get

O buffer possui tamanho limitado (n).O buffer possui tamanho limitado (n).Só podem ser inseridos produtos se o bufferSó podem ser inseridos produtos se o buffer

não estiver cheio.não estiver cheio.Só podem ser retirados produtos se o bufferSó podem ser retirados produtos se o buffer

não estiver vazio.não estiver vazio.

capacidade = n

Linguagens de Programacão [email protected] 22

Problema do ProdutorProblema do Produtor\\ConsumidorConsumidor

Solução utiliza três semáforos:Solução utiliza três semáforos:

FullFull: conta o número de : conta o número de slotsslots no no bufferbuffer que que estão ocupados; estão ocupados;

EmptyEmpty: conta o número de : conta o número de slotsslots no no bufferbuffer que que estão vazios; estão vazios;

MutexMutex: garante que os processos produtor e : garante que os processos produtor e consumidor não acessam o consumidor não acessam o bufferbuffer ao mesmo ao mesmo tempo; tempo;

12

Linguagens de Programacão [email protected] 23

# include “prototypes.h”# include “prototypes.h”# define N 100# define N 100

typedef int semaphore;typedef int semaphore;semaphore mutex = 1;semaphore mutex = 1;semaphore empty = N;semaphore empty = N;semaphore full = 0;semaphore full = 0;

void producer (void){void producer (void){int item;int item;while (TRUE){while (TRUE){produce_item(&item);produce_item(&item);P(&empty);P(&empty);P(&mutex);P(&mutex);enter_item(item); enter_item(item); V(&mutex);V(&mutex);V(&full);V(&full);

}}}}

void consumer (void){void consumer (void){int item;int item;while (TRUE){while (TRUE){P(&full);P(&full);P(&mutex);P(&mutex);remove_item(item); remove_item(item); V(&mutex);V(&mutex);V(&empty);V(&empty);consume_item(item);consume_item(item);

}}}}

Linguagens de Programacão [email protected] 24

DeadlockDeadlock

O uso inadequado de mecanismos de O uso inadequado de mecanismos de sincronização pode levar a situações em que sincronização pode levar a situações em que todos os threads de uma aplicação ficam todos os threads de uma aplicação ficam bloqueados a espera de uma condição que bloqueados a espera de uma condição que nunca ocorre.nunca ocorre.

O deadlock é um dos erros mais comuns em O deadlock é um dos erros mais comuns em aplicações multiaplicações multi--threads.threads.

13

Linguagens de Programacão [email protected] 25

Jantar dos FilósofosJantar dos Filósofos

process filosos [1=0 to 4]{while (true){pensar;pegar_garfos;comer;soltar_garfos;

}}

deadlock

Linguagens de Programacão [email protected] 26

Jantar dos FilósofosJantar dos Filósofossem garfo[5] = {1, 1, 1, 1, 1}sem garfo[5] = {1, 1, 1, 1, 1}process filosofo [1=0 to 3]{process filosofo [1=0 to 3]{while (true){while (true){P(garfo[i]);P(garfo[i+1]); P(garfo[i]);P(garfo[i+1]); comer;comer;V(garfo[i]);V(garfo[i+1]); V(garfo[i]);V(garfo[i+1]); pensar;pensar;

}}}}

process filosofo [4]{process filosofo [4]{while (true){while (true){P(garfo[0]);P(garfo[4]); P(garfo[0]);P(garfo[4]); comer;comer;V(garfo[0]);V(garfo[4]); V(garfo[0]);V(garfo[4]); pensar;pensar;

}}}}

Solução usando Solução usando semáforossemáforos

14

Linguagens de Programacão [email protected] 27

MonitoresMonitores

Monitores são construções utilizadas para a Monitores são construções utilizadas para a sincronização de threads que encapsulam um sincronização de threads que encapsulam um conjunto de procedimentos e variáveis.conjunto de procedimentos e variáveis.

Somente um thread pode estar ativo dentro do Somente um thread pode estar ativo dentro do monitor em qualquer instante.monitor em qualquer instante.

Outros threads interessados em executar rotinas de Outros threads interessados em executar rotinas de um monitor ficam bloqueados até que o thread ativo um monitor ficam bloqueados até que o thread ativo termine de executar o código do monitor.termine de executar o código do monitor.

Linguagens de Programacão [email protected] 28

MonitoresMonitoresmonitor example

int i;condition c;

procedure producer();.end;procedure consumer();.end;

end monitor;

15

Linguagens de Programacão [email protected] 29

MonitoresMonitoresMonitores utilizam variáveis condicionais que permitem que o Monitores utilizam variáveis condicionais que permitem que o thread em execução seja suspenso se uma determinada thread em execução seja suspenso se uma determinada condição não for observada.condição não for observada.

O bloqueio do thread ocorre através de uma chamada do tipo O bloqueio do thread ocorre através de uma chamada do tipo wait(variável condicional).wait(variável condicional).

Quando um thread é bloqueado em uma variável condicional, Quando um thread é bloqueado em uma variável condicional, um novo thread pode “entrar” no monitor.um novo thread pode “entrar” no monitor.

Threads bloqueados por variáveis condicionais podem ser Threads bloqueados por variáveis condicionais podem ser acordados através de uma chamada do tipo acordados através de uma chamada do tipo signal(variável signal(variável condicional)condicional) executada por outro thread.executada por outro thread.

O thread bloqueado só é ativado quando o thread ativo no O thread bloqueado só é ativado quando o thread ativo no monitor “sai” do monitor.monitor “sai” do monitor.

Linguagens de Programacão [email protected] 30

monitor Bounded_Buffer {monitor Bounded_Buffer {typeT buf[n]; typeT buf[n]; int front = 0,int front = 0,

rear = 0,rear = 0,count = 0;count = 0;

cond not_full,cond not_full,not_empty;not_empty;

procedure deposit (typeT data){procedure deposit (typeT data){while (count == n)while (count == n)wait (not_full);wait (not_full);

buf[rear] = data;buf[rear] = data;rear = (rear+1) % n;rear = (rear+1) % n;count++;count++;signal(not_empty);signal(not_empty);

end;end;procedure fetch(typeT &result){procedure fetch(typeT &result){while (count == 0)while (count == 0)wait (not_empty);wait (not_empty);

result = buf[front];result = buf[front];fornt = (fornt+1) % n;fornt = (fornt+1) % n;countcount----;;signal(not_full);signal(not_full);

}}} }

ProdutorProdutor\\consumidor consumidor usando monitoresusando monitores

16

Linguagens de Programacão [email protected] 31

Troca de MensagensTroca de MensagensUma segunda alternativa pra a sincronização entre Uma segunda alternativa pra a sincronização entre processos e threads é a troca de mensagens.processos e threads é a troca de mensagens.

É a única alternativa de sincronização em sistemas É a única alternativa de sincronização em sistemas distribuídos.distribuídos.

A troca de mensagens é geralmente implementada A troca de mensagens é geralmente implementada através de duas primitivas:através de duas primitivas:

send (destination,message)send (destination,message) -- envia para um envia para um determinado destino uma mensagem.determinado destino uma mensagem.

receive (source,message)receive (source,message) -- recebe a mensagem de recebe a mensagem de uma determinada fonte. uma determinada fonte.

Linguagens de Programacão [email protected] 32

Troca de MensagensTroca de MensagensAs chamadas As chamadas send send e e receivereceive podem ser síncronas ou podem ser síncronas ou assíncronas.assíncronas.

Em um Em um sendsend síncrono o thread que fez a invocação pode ficar síncrono o thread que fez a invocação pode ficar bloqueado até a mensagem ser recebida pela dispositivo de bloqueado até a mensagem ser recebida pela dispositivo de rede, ou mesmo até o recebimento de uma resposta.rede, ou mesmo até o recebimento de uma resposta.

No caso do No caso do receivereceive síncrono o thread que fez a invocação pode síncrono o thread que fez a invocação pode ficar bloqueado até que a mensagem desejada seja recebida.ficar bloqueado até que a mensagem desejada seja recebida.

Nas chamadas assíncronas o thread que fez a invocação nunca Nas chamadas assíncronas o thread que fez a invocação nunca fica bloqueado. fica bloqueado.

17

Linguagens de Programacão [email protected] 33

RPCRPC

A chamada de procedimento remoto (remote A chamada de procedimento remoto (remote procedure call) é um modelo de nível mais procedure call) é um modelo de nível mais alto para a troca de mensagens entre alto para a troca de mensagens entre processos.processos.

Permite a invocação de subrotinas entre Permite a invocação de subrotinas entre processos que estão sendo executados em processos que estão sendo executados em diferentes computadores de uma rede. diferentes computadores de uma rede.

A semântica de uma chamada remota é A semântica de uma chamada remota é semelhante a de uma chamada local.semelhante a de uma chamada local.

Linguagens de Programacão [email protected] 34

RPCRPC

processocliente

stub do cliente

interface de rede

cliente

1 10

2 9

processoservidor

stub do servidor

interface de rede

servidor

6 5

7 48

3

18

Linguagens de Programacão [email protected] 35

RPCRPC1.1. O processo cliente chama (chamada local) o stub do cliente, com O processo cliente chama (chamada local) o stub do cliente, com os parâmetros os parâmetros

apropriados;apropriados;

2.2. O stub organiza os parâmetros e monta uma mensagem, endereçada aO stub organiza os parâmetros e monta uma mensagem, endereçada ao servidor, que é o servidor, que é passada a interface de rede;passada a interface de rede;

3.3. A mensagem é enviada da máquina cliente para a máquina servidor;A mensagem é enviada da máquina cliente para a máquina servidor;

4.4. A interface de rede do servidor passa a mensagem ao stub do servA interface de rede do servidor passa a mensagem ao stub do servidor;idor;

5.5. O stub do servidor desmonta a mensagem, recupera os parâmetros, O stub do servidor desmonta a mensagem, recupera os parâmetros, e chama (chamada e chama (chamada local) o programa servidor, passando os parâmetros;local) o programa servidor, passando os parâmetros;

6.6. Após sua execução, o programa envia os eventuais resultados paraApós sua execução, o programa envia os eventuais resultados para o stub do servidor;o stub do servidor;

7.7. O stub do servidor monta uma mensagem, endereçada ao stub do cliO stub do servidor monta uma mensagem, endereçada ao stub do cliente, com a ente, com a indicação do fim da execução e com os resultados, e passa a mensindicação do fim da execução e com os resultados, e passa a mensagem à interface de agem à interface de rede;rede;

8.8. A mensagem é enviada da máquina servidor para a máquina cliente;A mensagem é enviada da máquina servidor para a máquina cliente;

9.9. A interface de rede do cliente passa a mensagem ao stub do clienA interface de rede do cliente passa a mensagem ao stub do cliente;te;

10.10. O stub do cliente desmonta a mensagem, recuperando a indicação dO stub do cliente desmonta a mensagem, recuperando a indicação do fim da execução o fim da execução e os resultados, e retorna da chamada local, passando o controlee os resultados, e retorna da chamada local, passando o controle e os resultados ao e os resultados ao cliente.cliente.

Linguagens de Programacão [email protected] 36

RMIRMIA invocação remota de métodos (remote method A invocação remota de métodos (remote method invocation) é semelhante à RPC, oferecendo um invocation) é semelhante à RPC, oferecendo um modelo de alto nível para a invocação de métodos de modelo de alto nível para a invocação de métodos de objetos remoto.objetos remoto.

É necessário que o programa cliente possua uma É necessário que o programa cliente possua uma referência remota para o objeto cujo método deseja referência remota para o objeto cujo método deseja invocar.invocar.

Isso é possível através de um servidor de nomes. O Isso é possível através de um servidor de nomes. O cliente envia ao servidor de nomes o nome de um cliente envia ao servidor de nomes o nome de um objeto, e recebe como resposta uma referência objeto, e recebe como resposta uma referência remota para o mesmo.remota para o mesmo.

19

Linguagens de Programacão [email protected] 37

Problemas na Utilização de ThreadsProblemas na Utilização de Threads

A necessidade de utilização de mecanismos de sincronização A necessidade de utilização de mecanismos de sincronização para o acesso a recursos compartilhados.para o acesso a recursos compartilhados.

A possibilidade de deadlock como resultado da utilização de A possibilidade de deadlock como resultado da utilização de mecanismos de sincronização.mecanismos de sincronização.

Uma maior dificuldade no processo de debug de um programa Uma maior dificuldade no processo de debug de um programa em decorrência da forma quase que aleatória com que os em decorrência da forma quase que aleatória com que os threads são ativados pelo escalonador.threads são ativados pelo escalonador.

Uma degradação do desempenho do sistema em função do Uma degradação do desempenho do sistema em função do aumento do número de threads ou da granularidade com que aumento do número de threads ou da granularidade com que são empregados os mecanismos de sincronização.são empregados os mecanismos de sincronização.

Linguagens de Programacão [email protected] 38

Programação Orientado a EventosProgramação Orientado a Eventos

Muitas aplicações são naturalmente estruturadas a Muitas aplicações são naturalmente estruturadas a partir da ocorrência de eventos externos. partir da ocorrência de eventos externos.

Sistemas interativos com interfaces gráficas, como Sistemas interativos com interfaces gráficas, como um processador de textos, executam funções quase um processador de textos, executam funções quase que exclusivamente como resposta a ações de que exclusivamente como resposta a ações de usuários.usuários.

A cada evento é associada uma reação, A cada evento é associada uma reação, representada por uma rotina ou representada por uma rotina ou handlerhandler, e o fluxo de , e o fluxo de processamento consiste num encadeamento de processamento consiste num encadeamento de reações.reações.

20

Linguagens de Programacão [email protected] 39

Programação Orientado a EventosProgramação Orientado a Eventos

Aplicações baseadas em eventos geralmente são Aplicações baseadas em eventos geralmente são compostas por um loop contínuo que aguarda pela compostas por um loop contínuo que aguarda pela ocorrência de eventos.ocorrência de eventos.

Assim que um evento é registrado um coletor de Assim que um evento é registrado um coletor de eventos insere um objeto associado ao evento em eventos insere um objeto associado ao evento em uma fila.uma fila.

Um processador de eventos retira os objetos da fila e Um processador de eventos retira os objetos da fila e executa as reações (rotinas) correspondentes.executa as reações (rotinas) correspondentes.

Linguagens de Programacão [email protected] 40

Programação Orientado a EventosProgramação Orientado a Eventos

fila de eventos

componente 1

componente 2

componente 3

processadorde eventos

eventoscoletorde eventos

21

Linguagens de Programacão [email protected] 41

Programação Orientado a EventosProgramação Orientado a Eventos

Os sistemas orientados a eventos podem ser Os sistemas orientados a eventos podem ser divididos em dois modelos.divididos em dois modelos.

No modelo preemptivo cada tipo de evento possui No modelo preemptivo cada tipo de evento possui uma prioridade, e a execução de uma reação uma prioridade, e a execução de uma reação associada a um evento é suspensa sempre que um associada a um evento é suspensa sempre que um evento de maior prioridade for recebido.evento de maior prioridade for recebido.

No modelo não preemptivo as reações são No modelo não preemptivo as reações são executadas de forma atômica, e novos eventos só executadas de forma atômica, e novos eventos só são tratados após ser completado o tratamento de são tratados após ser completado o tratamento de eventos anteriores.eventos anteriores.

Linguagens de Programacão [email protected] 42

Programação Orientado a EventosProgramação Orientado a Eventos

No modelo preemptivo não existe portanto a necessidade de No modelo preemptivo não existe portanto a necessidade de utilização de mecanismos como semáforos ou monitores para o utilização de mecanismos como semáforos ou monitores para o controle de acesso a recursos compartilhados.controle de acesso a recursos compartilhados.

A invocação das funções potencialmente bloqueantes segue A invocação das funções potencialmente bloqueantes segue sempre uma disciplina assíncrona, e os resultados são tratados sempre uma disciplina assíncrona, e os resultados são tratados através de handlers passados como parâmetros das chamadas.através de handlers passados como parâmetros das chamadas.

O maior problema da programação orientada a eventos é a O maior problema da programação orientada a eventos é a necessidade de “quebrar” o programa em blocos separados, o necessidade de “quebrar” o programa em blocos separados, o que pode dificultar a compreensão da linha de execução.que pode dificultar a compreensão da linha de execução.

22

Linguagens de Programacão [email protected] 43

void main (){void main (){do{do{receive(msg);receive(msg);print(msg);print(msg);

while(msg) while(msg) }}

} void function print_msg (string msg){} void function print_msg (string msg){if (msg){if (msg){print(msg);print(msg);receive (print_msg);receive (print_msg);

}}}}

void main() {void main() {receive (print_msg);receive (print_msg);

}}

Programação Orientado a EventosProgramação Orientado a Eventos

usando orientação a eventosusando orientação a eventos

Linguagens de Programacão [email protected] 44

ContinuaçõesContinuações

Uma continuação pode ser entendida como o que Uma continuação pode ser entendida como o que falta a ser computado em um programa.falta a ser computado em um programa.

Considere o programa:Considere o programa:x = 10; y =15; x = x+y; print (x);x = 10; y =15; x = x+y; print (x);

Após a instrução Após a instrução x=10x=10 a continuação éa continuação éy=15; x = x+y; print (x);y=15; x = x+y; print (x);

Após a instrução Após a instrução y = 15y = 15 a continuação éa continuação éy=15; x = x+y; print (x);y=15; x = x+y; print (x);

23

Linguagens de Programacão [email protected] 45

ContinuaçõesContinuaçõesAlgumas LPs, como C e Scheme, permitem a Algumas LPs, como C e Scheme, permitem a captura e representação explícita de uma captura e representação explícita de uma continuação.continuação.

Em Scheme uma continuação pode ser criada com a Em Scheme uma continuação pode ser criada com a função call/cc. função call/cc.

Em C continuações podem ser usadas através das Em C continuações podem ser usadas através das funções setjmp e longjmp.funções setjmp e longjmp.

Ao invocar uma continuação o programa abandona a Ao invocar uma continuação o programa abandona a execução corrente e retoma a execução execução corrente e retoma a execução representada pela continuação.representada pela continuação.

Linguagens de Programacão [email protected] 46

ExemploExemplo#include <setjmp.h>#include <setjmp.h>jmp_buf env;jmp_buf env;

void void int teste(){int teste(){

int i;int i;i = setjmp(env); // retorna 0 quando a continuaçãoi = setjmp(env); // retorna 0 quando a continuação

// é criada, ou o argumento de longjmp// é criada, ou o argumento de longjmpif (i=0){if (i=0){

... /* Faz alguma coisa*/... /* Faz alguma coisa*/if (erro)if (erro)

longjmp(env, erro); // chama a continuaçãolongjmp(env, erro); // chama a continuação......

} else {} else {printf(“Erro: %d/n”,i)printf(“Erro: %d/n”,i)

}}} }

24

Linguagens de Programacão [email protected] 47

CorotinasCorotinasCorotinas são construções que permitem que rotinas de um Corotinas são construções que permitem que rotinas de um programa possam ser executadas de forma alternada, em programa possam ser executadas de forma alternada, em intervalos intercalados no tempo.intervalos intercalados no tempo.

Enquanto threads são escalonados de forma preemptiva, Enquanto threads são escalonados de forma preemptiva, corotinas são escalonadas manualmente pelo programa através corotinas são escalonadas manualmente pelo programa através de chamadas específicas (de chamadas específicas (resume,resume, yield, transfer, etcyield, transfer, etc).).

Não existe portanto a necessidade de utilização de mecanismos Não existe portanto a necessidade de utilização de mecanismos como semáforos ou monitores para o controle de acesso a como semáforos ou monitores para o controle de acesso a recursos compartilhados.recursos compartilhados.

Poucas LPs suportam corotinas. Exemplos são Simula, Modula Poucas LPs suportam corotinas. Exemplos são Simula, Modula 2 e Lua a partir da versão 5.0.2 e Lua a partir da versão 5.0.

Linguagens de Programacão [email protected] 48

program exemplo;program exemplo;var i:item;var i:item;coroutine produtor;coroutine produtor;beginbegin

looploopproduzir(i);produzir(i);resume consumidor;resume consumidor;

end;end;end;end;

coroutine consumidor;coroutine consumidor;beginbegin

looploopconsumir(i);consumir(i);resume produtor;resume produtor;

end;end;end;end;beginbegin

resume produtor;resume produtor;end.end.

25

Linguagens de Programacão [email protected] 49

Corotinas Corotinas -- ImplementaçãoImplementaçãoNo modelo tradicional de invocação de subrotinas No modelo tradicional de invocação de subrotinas uma subrotina sempre está subordinada a outra.uma subrotina sempre está subordinada a outra.

Neste caso podeNeste caso pode--se usar uma única pilha para se usar uma única pilha para representar a execução de cada subrotina.representar a execução de cada subrotina.

Corotinas executam de forma cooperativa e não Corotinas executam de forma cooperativa e não subordinada. Não existe portanto uma hierarquia subordinada. Não existe portanto uma hierarquia natural entre elas.natural entre elas.

Para cada corotina é necessário uma pilha Para cada corotina é necessário uma pilha independente, já que sua linha de execução pode independente, já que sua linha de execução pode incluir a invocação de subrotinas.incluir a invocação de subrotinas.

Linguagens de Programacão [email protected] 50

CorotinasCorotinas

Árvore de pilhasÁrvore de pilhasou stack cactusou stack cactus