A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Linguagens Concorrentes Antonio Francisco do Prado

Apresentações semelhantes


Apresentação em tema: "Linguagens Concorrentes Antonio Francisco do Prado"— Transcrição da apresentação:

1 Linguagens Concorrentes Antonio Francisco do Prado Prado@dc.ufscar.br

2 Concorrência Multiprogramação: usada por um sistema "time- sharing". Um processador compartilhado por diversos processos; Multiprocessamento: vários processadores. Possibilita que múltiplos processos sejam executados em processadores distintos. Memória comum compartilhada para comunicação entre os processos. Processamento Distribuído: também requer processadores separados, mas cada um com sua memória. Processadores conectados via linhas de comunicação.

3 A concorrência é naturalmente dividida em nível de: instrução (executando duas ou mais instruções de máquina simultaneamente); comando (executando dois ou mais comandos simultaneamente); e unidade (executando dois ou mais programas simultaneamente). Concorrência Os métodos concorrentes aumentam a flexibilidade de programação e foram criados originalmente para serem usados em problemas particulares dos em sistemas operacionais.

4 Concorrência relaciona-se com fluxo de controle de um programa. Tem-se mais de um fluxo de controle ativo. É diferente da execução seqüencial de programas, onde se tem apenas um fluxo de controle, ou seja, em um determinado momento, existe uma única instrução candidata à execução. Unidades concorrentes podem ser executadas em: Um único processador ; Vários processadores que compartilham uma memória; Vários processadores independentes, sem compartilhamento de memória. Concorrência

5 Reduz o tempo total de processamento através de execução concorrente de diversas unidades; Aumenta a confiabilidade para aplicações críticas, onde não se torna confiável a execução em um único processador; Modela soluções que exploram a capacidade de máquinas com múltiplos processadores; Implementa aplicações distribuídas. Concorrência

6 Seção crítica Quando processos concorrentes interagem com variáveis compartilhadas, a integridade destas variáveis pode ser violada se o acesso não for coordenado. Uma seção crítica é um segmento de código de um processo que acessa um recurso compartilhado. Conceitos básicos Deadlock É uma situação onde um processo ou um conjunto de processos estão bloqueados, a espera de um evento que nunca irá acontecer.

7 Deadlock Um deadlock é caracterizado por uma espera circular Exemplo: o processo P1 está de posse do recurso r1, e precisa do recurso r2; o processo P2 está de posse de r2 e precisa de r1; Nesse caso, nenhum dos processos pode prosseguir, pois ambos dependem de recursos que não serão liberados. Conceitos básicos P1 r1r2 P2

8 Mecanismos de Sincronização Semáforos O conceito de semáforos consiste na colocação de proteções (guardas) no código que controlam o acesso a uma estrutura de dados. Em geral, a estrutura é uma fila, funcionando em regime FiFo(First in First out). A implementação do semáforo deve garantir que, uma vez que um processo inicie uma operação sobre um semáforo, nenhum outro processo terá acesso até que a operação conclua.

9 Conceitos básicos Tarefa Uma tarefa é uma unidade de um programa que pode estar em execução concorrente com outras unidades do mesmo programa. Uma tarefa pode comunicar-se com outras tarefas através variáveis não-locais compartilhadas, mensagens ou de parâmetros. As tarefas disjuntas ocorrem, se uma tarefa não se comunicar ou não afetar a execução de qualquer outra tarefa. Devem de alguma forma se comunicar para que haja sincronização em suas execuções, no compartilhamento de dados.

10 Conceitos básicos Tarefa tarefa1tarefa2Tarefa n Unidade concorrente

11 Sincronização de tarefas Sincronização é um mecanismo que controla a ordem de execução das tarefas. Conceitos básicos Cooperação A cooperação entre processos revela-se quando um processo aguarda que outro processo realize alguma tarefa, para prosseguir sua execução. Assim a cooperação entre as tarefas A e B ocorre, quando B precisa aguardar que A conclua alguma atividade específica antes de prosseguir sua execução.

12 Conceitos básicos Competição Ocorre quando ambas tarefas requerem algum recurso que não pode ser usado simultaneamente. Assim, se a tarefa A precisa acessar um dado compartilhado x que já esta sendo acessado pela tarefa B, a tarefa A precisa aguardar que B conclua seu acesso a x.

13 Conceitos básicos Competição Unidade Concorrente Tarefa T1 Tarefa T2 Enquanto T1 estiver acessando, T2 tem que esperar

14 Conceitos básicos Exclusão mútua Jantar dos filósofos Os filosofos tentam comer e para isso dependem do recurso (palito). Para comer os filósofos precisam de dois palitos. Caso um filosofo não esteja comendo, pode estar pensando ou dormindo. A Exclusão Mútua ou, simplesmente, Mutex, é um caso particular competição por recurso, onde apenas se pode permitir o acesso individual ao recurso(regiões críticas).Os primeiros mecanismos da exclusão mútua faziam com que os processos testassem continuamente o valor de uma variável que guarda o estado do recurso, até sua liberação, podendo causar um Deadlock.

15 Conceitos básicos Para que a competição por um recurso decorra sem qualquer problema são, normalmente, usados semáforos que permitem, ou não, o acesso de um ou mais processos à região crítica. Outros mecanismo de sincronização : Monitores; e Passagem de mensagem(rendezvous). Comportamento da comunicação entre tarefas: Síncrono Assíncrono

16 Monitores Os monitores podem ser utilizados como uma solução em ambiente concorrente transformando as estruturas de dados compartilhados em Tipos Abstratos de Dados, que agrupam as estruturas de dados com suas operações, e ocultam suas representações. Os monitores implementam a exclusão mútua, onde somente um processo pode estar ativo dentro do monitor em um instante de tempo. Mecanismos de Sincronização

17 Monitores (continuação) Quando um processo chama um método de um monitor, as primeiras instruções do método verificam se algum outro processo está ativo dentro dele. Se isto for verdade, o processo que chamou o método do monitor será suspenso até que o outro processo deixe o monitor. Se não houver nenhum processo ativo dentro do monitor, o processo poderá entrar e executar o método chamado. Mecanismos de Sincronização

18 Mecanismos Monitores Processos aguardando entrada

19 Passagem de mensagem A construção de monitores não moldam a sincronização em sistemas distribuídos, onde seria necessário a sincronização de unidades, na qual cada processador teria sua própria memória, em vez de uma única memória compartilhada. Para sincronizar os processos independentes é comum a utilização de monitores. Contudo, ao utilizarmos sistemas sem memória comum e com mais de um processador, a implementação dos monitores se torna inviável, porque não existe nenhum meio físico central. Surge assim uma técnica de encontros para tratar estes casos, que se faz através de mensagens. Mecanismos de Sincronização

20 rendezvous Uma tarefa pode ser projetada de modo a poder suspender sua execução em certo ponto, porque está ociosa ou porque precisa de informações de outra unidade antes que possa prosseguir. Se uma tarefa A quer enviar uma mensagem para a tarefa B, e se esta estiver disposta a receber, a mensagem poderá ser transmitida. Essa transmissão é chamada rendezvous. Mecanismos de Sincronização

21 Passagem de mensagem (Rendezvous) Mecanismos de Sincronização Processo Contínuo Processo Contínuo Processo Bloqueado

22 Linguagens Concorrentes Java (Multilinhas)

23 Multitarefas x Multilinhas Multitarefas - estão em espaço de endereçamento distinto e devem ser vistos como programas diferentes no mesmo sistema. Multilinhas - compartilham o mesmo espaço de endereçamento e dividem cooperativamente o mesmo processo. O modelo de Linhas de Execução de Java Java usa multilinhas de execução para permitir que todo o ambiente Java seja assíncrono. Não há um laço principal em um programa Java. Cada linha tem sua execução independente. Uma linha bloqueada não impede a execução das demais linhas. Sincronização A sincronização de recursos requeridos pelas linhas, executadas de forma assíncrona, é obtida pelo mecanismo Monitor. Em Java, não há uma classe monitor. Cada objeto tem seu próprio monitor, com seus métodos sincronizados. Quando uma linha está executando um método sincronizado, nenhuma outra linha pode executar este método. Multilinhas e Sincronização

24 Para criar programas concorrentes em Java reutiliza-se a classe Thread. A classe Thread encapsula todos os controles das linhas de execução. Um objeto Thread é o procurador de uma linha em execução. Quando um programa Java é iniciado já existe uma linha sendo executada. O programa principal de java é uma linha em execução. Thread class ThreadCorrente { public static void main(String args[ ]){ Thread t = Thread.currentThread( ); t.setName("Minha Linha"); System.out.println("Linha corrente: " + t); try{ for (int n = 5; n > 0; n --) { System.out.println ( " " + n); Thread.sleep(1000); } } catch (InterruptedException e) { System.out.println("interrompida"); } } //fim do main } Linha corrente: Thread [ Minha Linha,5,main ] 5 4 3 2 1 Resultado da execução

25 Java – Concorrência Classe Thread criado pronto executando esperando adormecido morto bloqueado start yield run wait sleep Completo (destroy) suspend resume notify notifyAll Acorda

26 sleep: passa como parâmetro um número inteiro de milissegundos que a thread deve permanecer interrompida; suspend: interrompe temporariamente a thread, que pode ser reiniciada posteriormente; resume: reinicia a thread; yield: passa o controle para outra thread; syncronized: faz com que um recurso seja acessado atomicamente; notify: libera um recurso sincronizado para a próxima thread; notifyAll: libera um recurso sincronizado para todas as threads; e wait: aguarda pela liberação de um recurso sincronizado. Threads Java Principais métodos

27 A sincronização de competição em Java é obtida especificando-se os métodos sincronizados que acessam dados compartilhados. A execução destes métodos deve ser concluída para que outra thread execute-os novamente. Cada método sincronizado coloca um bloqueio no objeto, que impede que outros métodos sejam executados sobre este objeto. Usa o modificador synchronized na definição do método. Java – Concorrência A entrada em um monitor de objetos, é feita pela chamada de um método marcado com synchronized. synchronized void metodo() {

28 Sincronização Autogenerated HTML roda.html

29 Sincronização import java.awt.*; class Chamado{ synchronized void Chama(String msg) { Applet1.ShowMessage(msg); //try {Thread.sleep(1000);} try { Thread.sleep((int)Math.random()*1000); } catch(Exception e){ } Applet1.ShowMessage(msg); } class Chamador implements Runnable { String msg; Chamado alvo; public Chamador(Chamado c, String s){ alvo = c; msg = s; new Thread(this).start(); } public void run(){ alvo.Chama(msg); }

30 Sincronização import java.applet.*; public class Applet1 extends Applet {public void init() { setLayout(null); setSize(426,266); button1 = new java.awt.Button(); button1.setLabel("Executar!"); button1.setBounds(324,72,66,94); button1.setBackground(new Color(12632256)); add(button1); list1 = new java.awt.List(4); add(list1); list1.setBounds(12,60,276,140); Acoes aAcoes = new Acoes(); button1.addMouseListener(aAcoes); } java.awt.Button button1; static java.awt.List list1; class Acoes extends java.awt.event.MouseAdapter { public void mouseClicked(java.awt.event.MouseEvent event) { Object object = event.getSource(); if (object == button1) executarThread(event); }

31 Sincronização void executarThread(java.awt.event.MouseEvent event) { Chamado alvo = new Chamado(); Thread corrente=Thread.currentThread(); ShowMessage(String.valueOf(corrente)); new Chamador(alvo,"Ola"); new Chamador(alvo,"Pessoal"); new Chamador(alvo,"Sincronizado"); ShowMessage("Fim criação chamador"); } static void ShowMessage(String s) { list1.addItem(s); } }// fim da classe Applet1

32 Java – Concorrência A sincronização de cooperação em Java é obtida com os métodos wait e notify definidos em na classe Object. O método wait é colocado em um laço que testa a condição de acesso a uma região crítica. Se a condição for falsa, a thread é colocada em uma fila de espera. O método notify é chamado para notificar uma thread, que a região crítica está liberada. wait e notify somente podem ser chamados de dentro de um método sincronizado. Usam o bloqueio do objeto realizado pelo syncronized.

33 Produtor e Consumidor Relogio procon.html

34 class Controle{ static int n; boolean flag1 = false; synchronized int get() { while(!flag1) //if(!flag1) try { wait(); } catch(InterruptedException e){ } Applet1.ShowMessage("Lendo: "+ String.valueOf(n)); flag1 = false; notify(); return n; } synchronized void put(int n) { while(flag1) //if(flag1) try { wait(); }catch(InterruptedException e){ } this.n = n; flag1 = true; Applet1.ShowMessage("Colocando: "+ n); notify(); } } Java – Produtor e Consumidor

35 class Produtor implements Runnable{ Controle c1; Produtor (Controle c1) { this.c1=c1; new Thread(this, "Produtor").start(); } public void run() { int i = 0; while(Controle.n < 10) { //while(true) c1.put(i++); } } class Consumidor implements Runnable{ Controle c1; Consumidor(Controle c1) { this.c1=c1; new Thread(this,"Consumidor").start(); } public void run(){ while(Controle.n < 10) { //while(true) c1.get(); } }

36 import java.awt.*; import java.applet.*; public class Applet1 extends Applet { public void init() { setLayout(null); setSize(426,266); button1 = new java.awt.Button(); button1.setLabel("button"); button1.setBounds(264,96,116,60); button1.setBackground(new Color(12632256)); add(button1); list1 = new java.awt.List(4); add(list1); list1.setBounds(12,36,222,194); SymMouse aSymMouse = new SymMouse(); button1.addMouseListener(aSymMouse); } java.awt.Button button1; static java.awt.List list1;

37 class SymMouse extends java.awt.event.MouseAdapter { public void mouseClicked(java.awt.event.MouseEvent event) { Object object = event.getSource(); if (object == button1) button1_MouseClicked(event); } void button1_MouseClicked(java.awt.event.MouseEvent event) { Controle c1 = new Controle(); new Produtor(c1); new Consumidor(c1); } static void ShowMessage(String s) { list1.addItem(s); }

38 Jantar dos filósofos

39 public class Palitos { private boolean[] catched = new boolean[5]; //vetor de Palitos - True(em uso) False(liberado) public Palitos( ) { } public synchronized void pick2(Filosofos f){ //método para pegar os 2 Palitos (sincronizado) Int key = f.getKey( ); //identifica o filósofo que quer pegar os Palitos while ( catched[key] || catched[((key +1)%5)] ){ //Espera até que seu Palito ou //o do seu vizinho à direita estiver em uso f.setStatus(2); //passa para o estado FAMINTO try{ wait( ); } //espera catch(Exception e){} } catched[key] = true; catched[((key +1)%5)] = true; f.setStatus(1); //passa para o estado COMENDO }//fim pick2

40 public synchronized void put2(Filosofos f){ // método para liberar os 2 Palitos usados int key; key = f.getKey( ); //identifica o filósofo que vai liberar os Palitos catched[key] = false; //libera o seu Palito //e o de seu vizinho à direita int aux = (key+1)%5; catched[aux] = false; try{ notifyAll( ); } //notifica que liberou os Palitos catch(Exception e){ } }//fim put2 }//fim da classe Palitos

41 public class Jantar { private Filosofos f0,f1,f2,f3,f4; public Palitos palito; public Jantar() { palito = new Palitos(); // cria objeto palitos f0 = new Filosofos(0,this); //cria threads filósofos f1 = new Filosofos(1,this); f2 = new Filosofos(2,this); f3 = new Filosofos(3,this); f4 = new Filosofos(4,this); f0.start(); f1.start(); f2.start(); f3.start(); f4.start(); } public static void main(String[] args) { new Jantar(); } public void SetInfo(int key, int status){ if (key == 0) { if (status ==0) { System.out.println("0 - Pensando"); } else if (status ==1) { System.out.println("0 - Comendo"); } else if (status ==2) { System.out.println("0 - Faminto"); } } else if (key == 1) { if (status ==0) { System.out.println("1 - Pensando"); } else if (status ==1) { System.out.println("1 - Comendo"); } else if (status ==2) { System.out.println("1 - Faminto"); } } else if (key == 2) { if (status ==0) { System.out.println("2 - Pensando"); } else if (status ==1) { System.out.println("2 - Comendo"); } else if (status ==2) { System.out.println("2 - Faminto"); } } else if (key == 3) { if (status ==0) { System.out.println("3 - Pensando"); } else if (status ==1) { System.out.println("3 - Comendo"); } else if (status ==2) { System.out.println("3 - Faminto"); } } else if (key == 4) { if (status ==0) { System.out.println("4 - Pensando"); } else if (status ==1) { System.out.println("4 - Comendo"); } else if (status ==2) { System.out.println("4 - Faminto"); } } } }

42 public class Filosofos extends Thread{ //cada filósofo é visto como um processo private int key; // identifica o filósofo private int status; // 0 = pensa, 1 = come, 2 = faminto private Jantar j; // objeto jantar public Filosofos(int key,Jantar j) { this.key = key; this.j = j; } public int getKey(){ // pega identificador do filósofo return key; } public void setStatus(int i){ // seta status do filósofo status = i; switch ( i ){ case 0 : j.SetInfo(key, 0); break; case 1 : j.SetInfo(key, 1); break; case 2 : j.SetInfo(key, 2); break; } }

43 private void pensando(){ // no estado pensando bloqueia //por um certo tempo 2000ms) try{Thread.sleep(2000);} catch(Exception e){} } private void comendo(){ // no estado comendo //bloqueia por um certo tempo (2500 ms) try{Thread.sleep(2500);} catch(Exception e){} } public void run(){ while(true){ // roda indefinidamente setStatus(0); // filósofo pensando pensando(); // pensa - bloqueia por certo tempo j.palito.pick2(this); // filósofo pega os Palitos comendo(); // come - bloqueia por certo tempo j.palito.put2(this); // libera os Palitos } } }//fim da classe Filosofos

44 3 Threads relogio Relogio relogio.html

45 import java.awt.*; class relogio extends Canvas implements Runnable { private Thread UmaThread; // declara a thread private Polygon UmPoligono; private int polyX[] = new int[9], //coordenadas X polyY[] = new int[9], //coordenadas Y posicao, //posicao da linha delay = 100; // sleep em milesegundos public relogio() { resize(130, 130); DefinePoligono(); UmPoligono = new Polygon(polyX, polyY, 9); posicao = 0; UmaThread = new Thread(this); / cria a thread UmaThread.start(); //inicia a thread }

46 public relogio(int _delay) // construtor da classe relogio { this(); if(_delay < 50) delay = 50; else if(_delay > 300) delay = 300; else delay = _delay; } public void reset() {posicao = 0;} public void resume() { UmaThread.resume(); } // resume( ) public void suspende() { UmaThread.suspend(); } // suspend ( ) public void destroy() { this.UmaThread = null; } // destroy ( ) public void run() // run do objeto Runnable, passado para a Thread { while (true) { repaint(); // chama o paint passando uma caneta gráfica try{ Thread.sleep(delay); } // sleep ( ) catch(InterruptedException e) { this.suspende(); } avancar(); }

47 //Desenha a linha do centro até a posição public void paint(Graphics g) { // chamado pelo repaint() g.drawPolygon(UmPoligono); g.drawLine(65, 65, polyX[posicao], polyY[posicao]); } private void avancar() { if(posicao < 6) posicao++; else posicao = 0; } //vetor com as coordenadas X e Y private void DefinePoligono() { polyX[0] = 37; polyX[1] = 97; polyX[2] = 129; polyX[3] = 129; polyX[4] = 97; polyX[5] = 37; polyX[6] = 1; polyX[7] = 1; polyX[8] = 37; polyY[0] = 1; polyY[1] = 1; polyY[2] = 37; polyY[3] = 97; polyY[4] = 129; polyY[5] = 129; polyY[6] = 97; polyY[7] = 37; polyY[8] = 1; } // fim DefinePoligono }// fim da classe relogio

48 import java.awt.*; import java.applet.*; public class Applet1 extends Applet { void suspende3_Clicked(java.awt.event.ActionEvent event) { pa3.suspende(); } void resume3_Clicked(java.awt.event.ActionEvent event) { pa3.resume(); } void suspende2_Clicked(java.awt.event.ActionEvent event) { pa2.suspende(); } void resume2_Clicked(java.awt.event.ActionEvent event) { pa2.resume(); } void suspende1_Clicked(java.awt.event.ActionEvent event) { pa1.suspende(); } void resume1_Clicked(java.awt.event.ActionEvent event) { pa1.resume(); }

49 void resetButton_Clicked(java.awt.event.ActionEvent event) { suspendeButton_Clicked(null); pa1.reset(); pa2.reset(); pa3.reset(); pa1.repaint(); pa2.repaint(); pa3.repaint(); } void suspendeButton_Clicked(java.awt.event.ActionEvent event) { pa1.suspende(); pa2.suspende(); pa3.suspende(); } void resumeButton_Clicked(java.awt.event.ActionEvent event) { pa1.resume(); pa2.resume(); pa3.resume(); }

50 public void init() { super.init(); setLayout(new BorderLayout(0,0)); setSize(507,300); mainButtonPanel = new java.awt.Panel(); mainButtonPanel.setLayout(new FlowLayout(FlowLayout.CENTER,20,10)); mainButtonPanel.setBounds(0,257,507,43); add("South", mainButtonPanel); resumeButton = new java.awt.Button(); resumeButton.setLabel("Resume todos"); resumeButton.setBounds(155,10,55,23); mainButtonPanel.add(resumeButton); suspendeButton = new java.awt.Button(); suspendeButton.setLabel("Suspende Todos"); suspendeButton.setBounds(230,10,55,23); mainButtonPanel.add(suspendeButton); resetButton = new java.awt.Button(); resetButton.setLabel("Resseta"); resetButton.setBounds(305,10,47,23); mainButtonPanel.add(resetButton); animationArea = new java.awt.Panel(); animationArea.setLayout(new GridLayout(1,3,0,0)); animationArea.setBounds(0,0,507,257); add("Center", animationArea); aPanel1 = new java.awt.Panel(); aPanel1.setLayout(new BorderLayout(0,0));

51 aPanel1.setBounds(0,0,507,257); aPanel1.setBackground(new Color(16711680)); animationArea.add(aPanel1); ap1 = new java.awt.Panel(); ap1.setLayout(new FlowLayout(FlowLayout.CENTER,5,25)); ap1.setBounds(0,0,169,224); aPanel1.add("Center", ap1); subP1 = new java.awt.Panel(); subP1.setLayout(new FlowLayout(FlowLayout.CENTER,5,5)); subP1.setBounds(0,224,169,33); aPanel1.add("South", subP1); resume1 = new java.awt.Button(); resume1.setLabel("Resume"); resume1.setBounds(43,5,39,23); subP1.add(resume1); suspende1 = new java.awt.Button(); suspende1.setLabel("Suspende"); suspende1.setBounds(87,5,39,23); subP1.add(suspende1); aPanel2 = new java.awt.Panel(); aPanel2.setLayout(new BorderLayout(0,0)); aPanel2.setBounds(169,0,169,257); animationArea.add(aPanel2); ap2 = new java.awt.Panel(); ap2.setLayout(new FlowLayout(FlowLayout.CENTER,5,25)); ap2.setBounds(0,0,169,224); aPanel2.add("Center", ap2); subP2 = new java.awt.Panel(); subP2.setLayout(new FlowLayout(FlowLayout.CENTER,5,5)); subP2.setBounds(0,224,169,33);

52 aPanel2.add("South", subP2); resume2 = new java.awt.Button(); resume2.setLabel("Resume"); resume2.setBounds(43,5,39,23); subP2.add(resume2); suspende2 = new java.awt.Button(); suspende2.setLabel("Suspende"); suspende2.setBounds(87,5,39,23); subP2.add(suspende2); aPanel3 = new java.awt.Panel(); aPanel3.setLayout(new BorderLayout(0,0)); aPanel3.setBounds(338,0,169,257); aPanel3.setBackground(new Color(255)); animationArea.add(aPanel3); ap3 = new java.awt.Panel(); ap3.setLayout(new FlowLayout(FlowLayout.CENTER,5,25)); ap3.setBounds(0,0,169,224); aPanel3.add("Center", ap3); subP3 = new java.awt.Panel(); subP3.setLayout(new FlowLayout(FlowLayout.CENTER,5,5)); subP3.setBounds(0,224,169,10); aPanel3.add("South", subP3); resume3 = new java.awt.Button(); resume3.setLabel("Resume"); resume3.setBounds(43,5,39,23); subP3.add(resume3); suspende3 = new java.awt.Button(); suspende3.setLabel("Suspende"); suspende3.setBounds(87,5,39,23); subP3.add(suspende3);

53 ap1.add(pa1); // adição da Thread pa1 ap2.add(pa2); // adição da Thread pa2 ap3.add(pa3); // adição da Thread pa3 Acoes lAcoes = new Acoes(); resumeButton.addActionListener(lAcoes); suspendeButton.addActionListener(lAcoes); resetButton.addActionListener(lAcoes); resume1.addActionListener(lAcoes); suspende1.addActionListener(lAcoes); resume2.addActionListener(lAcoes); suspende2.addActionListener(lAcoes); resume3.addActionListener(lAcoes); suspende3.addActionListener(lAcoes); } java.awt.Panel mainButtonPanel; java.awt.Button resumeButton; java.awt.Button suspendeButton; java.awt.Button resetButton; java.awt.Panel animationArea; java.awt.Panel aPanel1; java.awt.Panel ap1; java.awt.Panel subP1; java.awt.Button resume1; java.awt.Button suspende1; java.awt.Panel aPanel2; java.awt.Panel ap2; java.awt.Panel subP2; java.awt.Button resume2; java.awt.Button suspende2; java.awt.Panel aPanel3; java.awt.Panel ap3; java.awt.Panel subP3; java.awt.Button resume3; java.awt.Button suspende3;

54 relogio pa1 = new relogio(100); // criação da Thread pa1 relogio pa2 = new relogio(120); // criação da Thread pa2 relogio pa3 = new relogio(150); // criação da Thread pa3 class Acoes implements java.awt.event.ActionListener { public void actionPerformed(java.awt.event.ActionEvent event) { Object object = event.getSource(); if (object == resumeButton) resumeButton_Clicked(event); else if (object == suspendeButton) suspendeButton_Clicked(event); else if (object == resetButton) resetButton_Clicked(event); else if (object == resume1) resume1_Clicked(event); else if (object == suspende1) suspende1_Clicked(event); else if (object == resume2) resume2_Clicked(event); else if (object == suspende2) suspende2_Clicked(event); else if (object == resume3) resume3_Clicked(event); else if (object == suspende3) suspende3_Clicked(event); } } // fim da classe Ações } // fim da classe Applet1

55 Prioridades de Linha Quando uma linha de prioridade baixa está sendo executa e uma linha de prioridade mais alta torna-se ativa, ou sai de uma espera de E/S, ela é executada imediatamente. class Clicador implements Runnable { int clique = 0; private Thread t; private boolean rodando = true; public Clicador (int p) { t = new Thread(this); t.setPriority(p); } public void run( ) { while (rodando) { clique++; } public void stop( ) { rodando = false; } public void start( ) { t.start( ); } Threads - Prioridades

56 class PriAltaBaixa { public static void main (String args[ ]) { Thread.currentThread( ).setPriority(Thread.MAX_PRIORITY); Clicador alta = new Clicador( Thread.NORM_PRIORITY + 2); Clicador baixa = new Clicador( Thread.NORM_PRIORITY - 2); baixa.start( ); alta.start( ); try { Thread.sleep(10000); } catch (Exception e) { }; baixa.stop( ); alta.stop( ); System.out.println(baixa.clique + " vs." + alta.clique); } O resultado da execução deste programa é: c:\> java PriAltaBaixa 5785717 vs. 465881948 Threads - Prioridades

57 Bloqueio Mútuo class A { synchronized void foo(B b) { String name = Thread.currentThread().getName(); System.out.println(name + " entrou em A.foo"); try { Thread.sleep(1000);} catch (Exception e){ }; System.out.println(name + " tentando chamarB.last()"); b.last(); } synchronized void last() { System.out.println(" dentro de A.last"); } class B { synchronized void bar(A a) { String name = Thread.currentThread().getName(); System.out.println(name + " entrou em B.bar"); try { Thread.sleep(1000); } catch (Exception e) { }; System.out.println(name + "tentando chamarA.last()"); a.last(); } synchronized void last() { System.out.println(" dentro de B.last"); }

58 Bloqueio Mútuo (continuação) class Deadlock implements Runnable { A a = new A( ); B b = new B( ); Deadlock() { Thread.currentThread( ).setName("MainThread"); new Thread(this).start( ); a.foo(b);//consegue bloqueio a nesta linha. System.out.println("de novo na linha principal"); } public void run( ) { Thread.currentThread( ).setName("RacingThread"); b.bar(a);//consegue bloqueio em b em outra linha. System.out.println("de novo em outra linha"); } public static void main(String args[ ]) { new Deadlock( ); } } // fim da classe Deadlock

59 Bloqueio Mútuo (continuação) O resultado deste programa é: MainThread entrou em A.foo RacingThread entrou em B.bar MainThread tentando chamar B.last( ) RacingThread tentando chamar A.last( )

60 Java em Rede Sockets e Threads

61 import java.io.*; import java.net.*; public class Envia extends Thread { ObjectOutputStream os; Socket s; public Envia() { super(); try {//s=new Socket(InetAddress.getLocalHost()); // s = new Socket("200.18.99.130",12345); s = new Socket(localhost",12345); os = new ObjectOutputStream(s.getOutputStream()); } catch(Exception e) {} } public static void main(String args[]) { (new Envia()).start(); } public void run( ) { while (true) { try { os.writeObject(new Dados(1,"Testando dados")); os.flush(); } catch (Exception e) {} } } }

62 import java.net.*; import java.io.*; public class trata extends Thread { ObjectInputStream is; Socket s; public trata (Socket s) { this.s = s; try { is = new ObjectInputStream(s.getInputStream()); } catch (Exception e) {} } public void run( ) { while (true) { try { Dados d = (Dados) is.readObject(); System.out.println(d.i); System.out.println(d.a); (new Thread(d)).start(); }catch(Exception e) {} }

63 import java.io.*; import java.net.*; public class Recebe extends Thread { ServerSocket s; public Recebe() { super(); try { s = new ServerSocket(12345); }catch(Exception e) {} } public static void main(String args[]) { (new Recebe()).start(); } public void run( ) { try { (new trata(s.accept())).start(); }catch(Exception e) {} }

64 public class Dados extends Object implements java.io.Serializable, Runnable { public int i; public String a; public Dados (int i, String a) { this.i = i; this.a = a; } public void run () { System.out.println(Funcionou !!!!!!"); } Para executar: > Java Recebe Em outra janela DOS: > Java Envia

65 Explorando o java java.util.concurrent

66 Operações Atômicas Tipos: Integer, Long, Boolean, IntegerArray, e LongArray. Acesso sincronizado pelas threads, através de operações atômicas. Por exemplo: private AtomicLong val1 val1.incrementAndGet() val1.get() Pacote: import java.util.concurrent.atomic.*;

67 public class AtomicReference implements Serializable public AtomicReference() public AtomicReference(V initialValue) public final V get() public final void set(V newValue) public final boolean compareAndSet(V expect, V update) public final V getAndSet(V newValue) Pacote java.util.concurrent.atomic.AtomicReference ;

68 package atomico; import java.util.concurrent.atomic.AtomicReference; public class Atomica extends AtomicReference { public Atomica() { } public static void main(String args[]) { Atomica a = new Atomica(); a.set(Integer.MIN_VALUE); System.out.println("Teste1: " + a.get()); System.out.println("Teste2: " + a.getAndSet(22)); System.out.println("Teste1: " + a.get()); } Saída: Teste1: -2147483648 Teste2: -2147483648 Teste1: 22

69 menorNumero(1, 3, 2, 7); menorNumero(3, 6, 1, 8, 3, 9, 0); Argumentos variáveis public static Integer menorNumero (Integer a, Integer b) public static Integer menorNumero (Integer... numeros)

70 Usa padrão formatado de uma categoria sintática em Tempo de Compilação; Observações: List NÃO é Subtipo de List List NÃO é o Mesmo que List List É Subtipo de List Tipos Genéricos

71 List Lista de Qualquer Coisa extends (Leia, Que Seja Subtipo) List Lista de Qualquer Coisa que Seja Subtipo de Number super (Leia, Que Seja Supertipo) List Lista de Qualquer Coisa que Seja Supertipo de ArrayList

72 public interface Callable A task that returns a result and may throw an exception. Implementors define a single method with no arguments called call. The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.

73 public interface Executor An object that executes submitted Runnable tasks. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc.Runnable An Executor is normally used instead of explicitly creating threads. For example, rather than invoking new Thread(new(RunnableTask())).start() ; for each of a set of tasks, you might use: Executor executor = anExecutor ; executor.execute(new RunnableTask1()); executor.execute(new RunnableTask2());...

74 public interface ExecutorService extends Executor An Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks. An ExecutorService can be shut down, which will cause it to reject new tasks. Two different methods are provided for shutting down an ExecutorService. The ExecutorService. shutdown method will allow previously submitted tasks to execute before terminating, while the ExecutorService. shutdownNow method prevents waiting tasks from starting and attempts to stop currently executing tasks. Upon termination, an executor has no tasks actively executing, no tasks awaiting execution, and no new tasks can be submitted. An unused ExecutorService should be shut down to allow reclamation of its resources.

75 public interface ExecutorService extends Executor Method submit extends base method Executor.execute by creating and returning a Future that can be used to cancel execution and/or wait for completion. Methods invokeAny and invokeAll perform the most commonly useful forms of bulk execution, executing a collection of tasks and then waiting for at least one, or all, to complete. (Class ExecutorCompletionService can be used to write customized variants of these methods.) The Executors class provides factory methods for the executor services provided in this package.

76 Here is a sketch of a network service in which threads in a thread pool service incoming requests. It uses the preconfigured Executors.newFixedThreadPool factory method class NetworkService implements Runnable { private final ServerSocket serverSocket; private final ExecutorService pool; public NetworkService(int port, int poolSize ) throws IOException { serverSocket = new ServerSocket(port); pool = Executors.newFixedThreadPool(poolSize ); } public void run() { // run the service try { for (;;) { pool. execute (new Handler(serverSocket.accept())); } } catch (IOException ex) { pool.shutdown(); } } }

77 class Handler implements Runnable { private final Socket socket; Handler(Socket socket) { this.socket = socket; } public void run() { // read and service request on socket } The following method shuts down an ExecutorService in two phases, first by calling shutdown to reject incoming tasks, and then calling shutdownNow, if necessary, to cancel any lingering tasks.

78 void shutdownAndAwaitTermination(ExecutorService pool ) { pool. shutdown (); // Disable new tasks from being submitted try { // Wait a while for existing tasks to terminate if (! pool.awaitTermination(60, TimeUnit.SECONDS)) { pool.shutdownNow (); // Cancel currently executing tasks // Wait a while for tasks to respond to being cancelled if (! pool. awaitTermination(60, TimeUnit.SECONDS)) System.err.println("Pool did not terminate"); } } catch (InterruptedException ie) { // (Re-)Cancel if current thread also interrupted pool. shutdownNow (); // Preserve interrupt status Thread.currentThread().interrupt(); } }

79 public interface Future Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready. Cancellation is performed by the cancel method. Additional methods are provided to determine if the task completed normally or was cancelled. Once a computation has completed, the computation cannot be cancelled. If you would like to use a Future for the sake of cancellability but not provide a usable result, you can declare types of the form Future and return null as a result of the underlying task. Parâmetros: V - The result type returned by this Future's get method

80 Future submit(Callable task) void shutdown() List shutdownNow() boolean awaitTermination (long timeout, TimeUnit unit) throws InterruptedException

81 interface ArchiveSearcher { String search(String target); } class App { ExecutorService executor =... ArchiveSearcher searcher =... void showSearch(final String target) throws InterruptedException { Future future = executor.submit ( new Callable () { public String call() { return searcher.search ( target); }}); displayOtherThings(); // do other things while searching try { displayText (future.get()); // use future } catch (ExecutionException ex) { cleanup(); return; } } } The FutureTask class is an implementation of Future that implements Runnable, and so may be executed by an Executor. FutureTask For example, the above construction with submit could be replaced by: FutureTask future = new FutureTask (new Callable () { public String call() { return searcher.search(target); }} ); executor.execute(future );

82 public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) public ScheduledFuture scheduleWithFixedDelay (Runnable command, long initialDelay, long delay, TimeUnit unit) Tarefas Agendadas

83 public interface BlockingQueue extends Queue A Queue that additionally supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available in the queue when storing an element. A BlockingQueue does not accept null elements.

84 class Producer implements Runnable { private final BlockingQueue queue; Producer(BlockingQueue q) { queue = q; } public void run() { try { while (true) { queue.put(produce()); } } catch (InterruptedException ex) {... handle...} } Object produce() {... } } Exemplo Produtor e Consumidor

85 class Consumer implements Runnable { private final BlockingQueue queue; Consumer(BlockingQueue q) { queue = q; } public void run() { try { while (true) { consume(queue.take()); } } catch (InterruptedException ex) {... handle...} } void consume(Object x) {... } } class Setup { void main() { BlockingQueue q = new SomeQueueImplementation(); Producer p = new Producer(q); Consumer c1 = new Consumer(q); Consumer c2 = new Consumer(q); new Thread(p).start(); new Thread(c1).start(); new Thread(c2).start(); }

86 public class ArrayBlockingQueue extends AbstractQueue implements BlockingQueue, Serializable A bounded blocking queue backed by an array. This queue orders elements FIFO (first-in-first-out). The head of the queue is that element that has been on the queue the longest time. The tail of the queue is that element that has been on the queue the shortest time. New elements are inserted at the tail of the queue, and the queue retrieval operations obtain elements at the head of the queue.

87 public class CountDownLatch extends Object A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the CountDownLatch.countDown method, after which all waiting threads are released and any subsequent invocations of await return immediately.

88 package geral.reflex; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class TesteReflection {... public static void main(String[] args) { Field[] campos = TesteReflection.class.getDeclaredFields(); for (Field campoAtual : campos) { System.out.println(campoAtual.getName() + ": " + campoAtual.getType().getName()); } Meta Classes

89 Constructor [] constr = (Constructor []) TesteReflection.class.getDeclaredConstructors (); System.out.println("Construtores de TesteReflection:"); for (Constructor constrAtual : constr) { try { Class [] params = constrAtual.getParameterTypes (); System.out.print("\t"); System.out.print(Modifier.toString(constrAtual.getModifiers())); System.out.print(" TesteReflection("); if (params.length > 0) { System.out.print(params[0]. getName ()); for (int i = 1; i < params.length; i++) { System.out.print(", "); System.out.print(params[i]. getName ()); } System.out.println(")"); } catch (Exception e) { e.printStackTrace(); }

90 TesteReflection var = new TesteReflection("Primeiro Teste"); try { Field campo = TesteReflection.class.getDeclaredField ("algo"); System.out.println("\nCampo: " + campo + " contendo: " + campo.get(var)); Method metodo = TesteReflection.class.getDeclaredMethod("getAlgo"); if (metodo != null) { System.out.println(metodo.getName()+ " retorna: "+ metodo.invoke(var)); } } catch (Exception e) { e.printStackTrace(); }

91 Outras Linguagens Concorrentes: Ada Modula

92 Ada – Introdução Ada é uma linguagem de programação de alto nível e imperativa baseada em Pascal e criada através de um concurso realizado pelo Depto. de Defesa dos EUA. O nome Ada é uma homenagem a condessa de Lovelace, Augusta Ada Byron, filha de Lord Byron que trabalhou com Charles Babbage e é considerada como a primeira programadora de computadores da História.

93 Grande capacidade numérica tornando-a útil para uso acadêmico; Foi projetada para detectar erros não apenas durante a compilação mas também em tempo de execução; Foi feita para implementar programas rápidos e para ser usada em máquinas que usam computadores para fins militares; É uma linguagem estruturada, imperativa e fortemente tipada; Ada 95 suporta programação orientada ao objeto e permite interfaces com C/C++, FORTRAN e também com Java; Ada – Características

94 Ada – Estruturas básicas Declarações de eventuais bibliotecas Procedure nome_do_programa is Declarações de possíveis variáveis Begin Corpo do programa End nome_do_programa; Exemplo: with Text_IO; use Text_IO; procedure alomundo is begin Put_Line("Alo Mundo!!!"); end alomundo;

95 Ada – Estruturas básicas Declaração de Variáveis. Nome_variável : tipo_variável [:= valor]; Comentário Tudo o que estiver a direita de "--" é comentário no programa. Declaração de bibliotecas With Ada.Text_IO;

96 Ada – Comandos IF if condição then seqüência de comandos elsif condicao2 then seqüência de comandos2 else outra seqüência de comandos end if; FOR for a in 1..10 loop sequencia de comandos end loop;

97 Ada – Comandos While while a /=3 and b <=15 and c=3.0 loop seqüência de comandos end loop; Case case x is when 1 => executa alguma coisa when others => Put_Line("Oi"); end case; Loop-laço loop seqüência de comandos end loop;

98 Ada – Concorrência A concorrência em Ada pode ser expressada através de tarefas (tasks). São entidades passivas que fornecem serviços de gerenciamento para dados compartilhados armazenados neles. Eles fornecem seus serviços, mas somente quando eles são solicitados. As tarefas Ada possuem diversos mecanismos que permitem a escolha entre solicitações concorrentes para acesso a seus recursos. As tarefas são declaradas em duas partes, uma de especificação e uma de corpo através das clausula entry e accept.

99 Ada – Concorrência As tarefas comunicam-se usando mecanismo de passagem de mensagem (rendezvous); Quando um accept recebe uma mensagem que não está preparado para aceitar, a tarefa emissora deve ser suspensa até que a tarefa receptora esteja preparada para receber a mensagem Accept trabalha com uma fila associada; Task body Tarefa is begin loop Accept entrada(parametros) do.................. end entrada; end loop; end tarefa;

100 Ada – Concorrência Um outro exemplo mostra como mais de uma tarefa são tratadas: Task body tarefa is loop select accept entrada_1 (parâmetros) do..... end entrada_1; or accept entrada_2 (parâmetros) do..... end entrada_2; end select; end loop; end tarefa; Fila O select examina as filas selecionando qual accept será executado primeiro Seção crítica controlada pelos comandos Accept e select

101 Ada – Concorrência Pode ser feita também a sincronização de competição, onde a clausula accept pode ter uma proteção(guarda) anexada, na forma do comando when podendo retardar o mecanismo. when not cheio(buffer) => accept deposita(novo) do Um accept com um when pode ser aberto ou fechado. Se a expressão boolena da when for verdadeira, accept será aberto e estará sempre disponível para rendezvous, caso contrário será fechado e não poderá ter rendezvous.

102 Ada – Concorrência with Ada.Integer_text_IO,Ada.Text_IO; use Ada.Integer_Text_IO,Ada.Text_IO; -- Bibliotecas usadas -- procedure Prod_Cons is -- Procedimento principal -- --Declaração da tarefa buffer e seus métodos-- task buffer is entry deposita(ITEM : in INTEGER); entry busca(ITEM : out INTEGER); end buffer; --Estrutura corpo do buffer-- task body buffer is tambuffer:constant INTEGER :=100; buf : array(1..tambuffer) of INTEGER; preenchido : INTEGER range 0..tambuffer := 0; prox_in,prox_out : INTEGER range 0..tambuffer := 1; ITEM : INTEGER; Produtor/consumidor Define o nome do método que será usado na concorrência

103 begin loop select when preenchido accept deposita(ITEM :in INTEGER) do buf(prox_in) := ITEM; end deposita; prox_in := (prox_in mod tambuffer) + 1; preenchido := preenchido + 1; or when preenchido > 0 => accept busca(ITEM : out INTEGER) do ITEM := buf(prox_out); end busca; prox_out := (prox_out mod tambuffer) + 1; preenchido := preenchido - 1; end select; end loop; end buffer; Ada – Concorrência o accept determina quem vai entrar para acessar o recurso seleciona qual método será usado

104 task produtor; task consumidor; task body produtor is novo_valor : INTEGER; begin loop buffer.deposita(novo_valor); put_line("Produzindo..."); end loop; end produtor; task body consumidor is valor_armazenado : INTEGER; begin loop buffer.busca(valor_armazenado); put_line("Consumindo..."); -- consome valor_armazenado -- end loop; end consumidor; end Prod_Cons; Ada – Concorrência Declarações das tarefas que vão acessar os métodos do buffer Os métodos estão sendo chamados da task buffer, que é comum as outras tarefas

105 Ada – Concorrência Objetos Protegidos Oferece sincronização por competição que não envolve o mecanismo de rendezvous. Podem ser acessados ou por sub-programas protegidos ou por entradas similares existentes em tarefa. As chamadas de entrada a um objeto protegido proporcionam comunicação síncrona com uma ou mais tarefas usando o mesmo objeto protegido Esses objetos oferecem acesso mutuamente exclusivo de leitura e escrita aos dados e funções do objeto, que oferecem acesso concorrente.

106 Ada – Concorrência protected body buffer is accept deposita(ITEM :in INTEGER) do when preenchido < tambuffer is begin buf(prox_in):= ITEM; prox_in := (prox_in mod tambuffer) + 1; preenchido := preenchido + 1; end deposita; accept busca(ITEM : out INTEGER) when preenchido > 0 is begin ITEM := buf(prox_out); prox_out := (prox_out mod tambuffer) + 1; preenchido := preenchido - 1; end busca; end loop; end buffer;

107 Ada – Concorrência with TEXT_IO, SEMAPHORES; use TEXT_IO, SEMAPHORES; procedure EXAMPLE is SCREEN : SEMAPHORE; task ONE; task body ONE is begin loop WAIT (SCREEN); PUT_LINE (Tarefa 1"); SIGNAL (SCREEN); end loop; end ONE; Semáforos Nesse exemplo estão implementadas duas tarefas, que são controladas pelo semáforo task TWO; task body TWO is begin loop WAIT (SCREEN); PUT_LINE (Tarefa 2"); SIGNAL (SCREEN); end loop; end TWO; begin INITIAL (SCREEN, 1); end EXAMPLE;

108 Ada – Concorrência Tela do programa Ada+SQL

109 Modula – Introdução Criada em 1975 pelo professor Niklaus Wirth, criador da linguagem Pascal linguagem segura, confiável e com muito mais recursos que o Pascal; Apresenta as seguintes características:

110 Modula – Características Linguagem fortemente tipada, com grande variedade de tipos e estruturas de controle; Faz menos uso de blocos (begin...end), otimizando estruturas de controle como if e for; Eliminou o label e goto; Capacidade de criar programas utilizando multi- processamento através de co-rotinas; Case sensitive

111 Modula Estruturas Básicas MODULE Nome_Programa; Declaração de bibliotecas; Declaração de variáveis; Begin Corpo do programa; End Nome_programa. Exemplo: MODULE Exemplo; FROM InOut IMPORT WriteString, WriteInt, WriteLn; VAR digito: INTEGER; BEGIN WriteString(âlo mundo); END Exemplo. (* Fim do Programa*)

112 Declaração de bibliotecas FROM IO IMPORT WriteString,WriteCard,Writeln; Declaração de variáveis VAR Nome_variável : Tipo_da_variável; Comentário Tudo que estiver entre ( *....*) é comentário do programa. Modula Estruturas Básicas

113 Modula – Comandos IF Exemplo: IF maior > menor THEN Verdade := maior ELSE HALT; END; Case CASE variável OF constante 1: comando 1; constante 2: comando 2; constante n: comando n; END;

114 Modula – Comandos While WHILE condição DO comandos; END; Repeat REPEAT comandos; UNTIL condição; Loop LOOP Seqüência de Estruturas END

115 Modula – Comandos For soma :=0; FOR i :=1 TO n BY 2 DO soma := soma + i * i END; With WITH designador DO SeqComandos END;

116 Uma declaração de procedure deve ter: o nome da procedure; informação sobre os parâmetros da procedure(se existirem); o tipo de valor que a procedure retorna (se é uma função); declaração das entidades que pertencem à procedure; uma seqüência de estruturas para serem executadas quando a procedure é chamada. Sintaxe: procedure ; OU procedure ( parâmetros ); Modula – Declarações

117 Função São métodos que realizam cálculos e retornam um valor. Exemplo: PROCEDURE potencia (x:REAL; i:INTEGER):REAL; VAR z:REAL; BEGIN z:=1.0; WHILE i>0 DO IF ODD(i) THEN z:=z*x END; x:= x*x; i:=i DIV 2; END; RETURN z; END potencia;

118 Os módulos são características que distinguem o Modula do seu ancestral, o Pascal; Todo programa em Modula é um módulo, ou, na maioria das vezes, é formados por um programa módulo (programa principal), e por um número qualquer de módulos de biblioteca; Módulos locais, declarados dentro de outros módulos ou procedures; Nem todas as entidades pertencem a um módulo assim como nem todas entidades declaradas em outros módulos estão disponíveis para este módulo; Modula – Módulos

119 Modula – Concorrência Pode-se definir um processo como sendo um programa em execução; Definimos concorrência quando dois ou mais processos são executados simultaneamente sem que nenhum destes seja prejudicado ; Em Modula implementa-se "concorrência" através das Co-rotinas.

120 Definição de um Módulo Processes: DEFINITION MODULE Processes; TYPE SIGNAL; PROCEDURE StartProcess(P:PROC; n:INTIGER); (*inicia um processo concorrente*) PROCEDURE SEND(VAR s:SIGNAL); (*um processo esperando por um s é continuado*) PROCEDURE WAIT(VAR s:SIGNAL); (*espera algum processo enviar s*) PROCEDURE Awaited(s:SIGNAL):BOOLEAN; (*Acordado(s)=pelo menos um processo espera por s*) (*Acordado(s)=pelo menos um processo espera por s*) PROCEDURE Init(VAR s:SIGNAL); (*inicialização compulsória*) END Processes. Modula – Concorrência

121 As Co-rotinas são implementadas a partir da procedure NewProcess; Co-rotinas necessitam de programas ou procedures que manipulem valores de endereços de memória, pois elas agem diretamente no hardware do computador; Na chamada da procedure NewProcess deve ser especificada em qual será criada a Co- rotina, o Workspace que é o bloco de memória onde será armazenado o estado da Co-rotina, o endereço de memória do Workspace,o tamanho do Workspace e a referência para a nova Co-rotina;

122 Sintaxe de NewProcess: Procedure NewProcess ( P : Procedure; A : Address "endereço do Workspace"; S : Cardinal "tamanho do Workspace"; Var E : Address "referência para nova Co-rotina"); Antes de chamarmos a procedure NewProcess devemos alocar memória para a Workspace, pois é nela que ficam as variáveis locais, a Co-rotina e a pilha de Co-rotinas e outras informações. Para criarmos a Workspace devemos declarar um array de Bytes ou Words. Também devemos criar uma variável do tipo Address, que retornará o endereço e o tamanho do Workspace(ADR e SIZE). Modula – Concorrência

123 A procedure Transfer tem a função de transferir o controle de execução de uma Co-rotina para outra caracterizando a concorrência, ela também é fundamental para executar as Co-rotinas, pois NewProcess apenas prepara a Co-rotina para a execução. Esta é a sintaxe da procedure Transfer: Procedure Transfer ( A, B : Address); Quando a procedure Transfer é chamada, ela interrompe a Co-rotina que está sendo executada no momento, que é referenciada por A, e inicia a outra que é referenciada por B. A procedure Transfer deve ser importada de System. Modula – Concorrência

124 MODULE Aplic; FROM Nucleo IMPORT CriarProcesso, DestruirProcesso, Boot, EnviarMsg, ReceberMsg, TipoNome, TipoMsg, TamNome, TamMsg, Sempre, NemSempre,EscreveFrase, EscreveInt,Incrementa,MaiorIgual,Atribui; FROM InOut IMPORT WriteCard, WriteLn, WriteString, WriteInt; CONST TamBuffer = 10; TYPE TipoBuffer = ARRAY[0..TamBuffer-1] OF TipoMsg; VAR BufferIn,BufferOut : TipoBuffer; In,Out : INTEGER; Flag : BOOLEAN; Modula – Concorrência

125 PROCEDURE InicializaBuffer; VAR I : CARDINAL; BEGIN BufferIn[0] := 'MENSAGEM BUFFERIZADA NUMERO 1'; BufferIn[1] := 'MENSAGEM BUFFERIZADA NUMERO 2';.... BufferIn[10] := 'MENSAGEM BUFFERIZADA NUMERO 11'; FOR I := 0 TO (TamBuffer - 1) DO BufferOut[I] := ' '; END; (* FOR *) In := 0; Out := 0; END InicializaBuffer; Modula – Concorrência

126 PROCEDURE PoeNoBuffer(Msg : TipoMsg); BEGIN EscreveFrase('VAI POR NO BUFFER'); EscreveFrase(Msg); EscreveInt(Out); Atribui(BufferOut[Out],Msg); Incrementa(Out); END PoeNoBuffer; PROCEDURE TiraDoBuffer(VAR Msg : TipoMsg); BEGIN EscreveFrase('VAI TIRAR DO BUFFER'); EscreveInt(In); Atribui(Msg,BufferIn[In]); Incrementa(In); EscreveFrase(Msg); END TiraDoBuffer; Modula – Concorrência O produtor e o Consumidor acessam Esses métodos de modo concorrente

127 PROCEDURE Produtor; VAR Msg : TipoMsg; Flag : BOOLEAN; BEGIN EscreveFrase('ENTROU NO PRODUTOR'); LOOP TiraDoBuffer(Msg); EnviarMsg(Msg,'C1',Flag); IF MaiorIgual(In,TamBuffer) THEN DestruirProcesso(NemSempre,Flag); END; (* IF *) END; (* LOOP *); EscreveFrase('SAIU DO PRODUTOR'); END Produtor; Modula – Concorrência O produtor é criado no inicio do programa se o buffer estiver cheio, ele é destruído

128 PROCEDURE Consumidor; VAR Msg : TipoMsg; Flag : BOOLEAN; BEGIN EscreveFrase('ENTROU NO CONSUMIDOR'); LOOP ReceberMsg(Msg,Flag); IF Flag THEN PoeNoBuffer(Msg); END; IF MaiorIgual(Out,TamBuffer) THEN DestruirProcesso(NemSempre,Flag); END; (* IF *) END; (* LOOP *) EscreveFrase('SAIU DO CONSUMIDOR'); END Consumidor; Modula – Concorrência


Carregar ppt "Linguagens Concorrentes Antonio Francisco do Prado"

Apresentações semelhantes


Anúncios Google