Programação Concorrente na Linguagem Vale 4



Documentos relacionados
Monitores. Conceito Sistemas Operacionais II

Vale4 - Uma Linguagem Didática para Ensino de Programação Concorrente

Sistemas Operacionais

Sistemas Operacionais Aula 08: Sincronização de Processos. Ezequiel R. Zorzal

O PROBLEMA DOS LEITORES E ESCRITORES LABORATORIO 1

Sincronização de Processos (4) Monitores

Sistemas Operacionais

Monitores. Setembro de Monitores

Sincronização. Cooperação entre Processos

Programação Concorrente

Programação distribuída e paralela (C. Geyer) RPC 1

Fundamentos. Módulo 6: Sincronização de Processos. Bounded-Buffer (Cont.) Bounded-Buffer

BC1518-Sistemas Operacionais. Prof. Marcelo Z. do Nascimento

Representação de Algoritmos - Linguagens de Programação

Estrutura de Dados. Introdução a Ponteiros. Prof. Gerson Borges Estrutura de Dados I 1

Remote Procedure Call. Programação distribuída e paralela (C. Geyer) RPC 1

Sistemas Operacionais Sincronização e Comunicação entre Processos

9 - Sincronização e Comunicação entre Processos

Geração de código intermediário. Novembro 2006

Processos. Adão de Melo Neto

Revisão Ultima aula [1/2]

Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO

Notas da Aula 6 - Fundamentos de Sistemas Operacionais

Conceito de processo como uma unidade de trabalho em um sistema moderno de tempo compartilhado. Estados de um processo.

O modelo do computador

Sintaxe e Semântica. Fases da Compilação. programa fonte

PROGRAMAÇÃO CONCORRENTE

Sincronização e Comunicação entre Processos. Adão de Melo Neto

Concorrência e Paralelismo

MC504 - Sistemas Operacionais

Curso: Ciência da Computação Disciplina: Construção de Compiladores Período: Prof. Dr. Raimundo Moura

IFPE. Disciplina: Sistemas Operacionais. Prof. Anderson Luiz Moreira

PROGRAMA DE DISCIPLINA

IFTO TÉCNICO EM INFORMÁTICA DESENVOLVIMENTO DE SISTEMAS AULA 01

Programação Básica em Arduino Aula 2

Linguagem de Programação Introdução a Linguagem Java

Sistemas Operacionais

Manipulação de Arquivos em Pascal

Algoritmos e Linguagem de Programação I

Sistemas Operacionais. Técnicas de Implementação de Exclusão Mútua. Aula VI Prof. Rosemary Silveira

Disciplina: Sistemas Operacionais - CAFW-UFSM Professor: Roberto Franciscatto

Curso Técnico em Redes

Comunicação em Sistemas Distribuídos. Conceitos: Paradigma C/S. Conceitos: Paradigma C/S. Paradigma Cliente/Servidor

Algumas notas sobre PASCAL

CAPÍTULO 7 NÍVEL DE LINGUAGEM DE MONTAGEM

Componentes do Computador e. aula 3. Profa. Débora Matos

Sockets em Ruby. Curso de Tecnologia em Redes de Computadores Programação para Redes

Sistemas Operacionais. Capítulo 7 Sincronização e Comunicação entre Processos

Programação WEB. Prof. André Gustavo Duarte de Almeida docente.ifrn.edu.br/andrealmeida. Aula III Introdução PHP

Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO

7. ESTRUTURAS DE DADOS ESTÁTICAS E DINÂMICAS

Síntese. Compiladores. Geração de código intermediário. Linguagens Intermediárias. Modelo Clássico. Linguagens Intermediárias. Código intermediário

Geração de código. Ivan Ricarte INTRODUÇÃO À COMPILAÇÃO

Problemas Clássicos de Sincronização

Algoritmos I Aula 13 Java: Tipos básicos, variáveis, atribuições e expressões

Sistemas Operacionais. Conceitos de um Sistema Operacional

PROGRAMAÇÃO II 3. FILA DINÂMICA

2 echo "PHP e outros.";

(Aula 17) Threads em Java

Métodos de Sincronização do Kernel

Sistemas Distribuídos

Computação Concorrente (MAB-117) Monitores

INTRODUÇÃO OBJECT PASCAL/DELPHI

SIMULADOR DE ROTEAMENTO DE PACOTES (V. 3 20/05/2010)

Curso Adonai QUESTÕES Disciplina Linguagem JAVA

IES-300. Tecnologia em Análise e Desenvolvimento de Sistemas Prof. Me. Álvaro d Arce alvaro@darce.com.br

Sistemas Operacionais INF Prof. José Gonçalves

Conceitos de Sistemas Operacionais: Chamadas de Sistema. Prof Rafael J. Sandim

Nesta aula serão apresentados alguns comandos de condição, repetição e gráficos.

CURSO DE PROGRAMAÇÃO EM JAVA

- UNIVERSIDADE DO VALE DO RIO DOS SINOS CIÊNCIAS EXATAS E TECNOLÓGICAS Curso: Informática / Ciência da Computação

Ciclo de Vida de um Processo

Notas da Aula 4 - Fundamentos de Sistemas Operacionais

Universidade da Beira Interior. Sistemas Distribuídos

Programação Estruturada. Programação Estruturada. Idéias Básicas da Programação Estruturada

JSP - ORIENTADO A OBJETOS

Programação Orientada a Objetos Threads

UNIVERSIDADE FEDERAL DO RIO GRANDE DO SUL INSTITUTO DE INFORMÁTICA INFORMÁTICA APLICADA

Programação Concorrente Processos e Threads

SISTEMAS OPERACIONAIS

Threads em Java. Sistemas Operacionais - Laboratório Professor Machado

PROGRAMA DE DISCIPLINA

Safeweb DLL biblioteca para desenvolvimento

Sistemas Operacionais

Sistemas Operacionais

OPERADORES E ESTRUTURAS DE CONTROLE

AULA 1: PARADIGMAS DE PROGRAMAÇÃO

UNIVERSIDADE DO OESTE DE SANTA CATARINA CAMPUS DE SÃO MIGUEL DO OESTE

Um processo sob UNIX ocupa uma área de memória formada basicamente por 3 partes:

Sistemas Operativos: Concorrência (Parte 2)

Curso : Tecnologia em Desenvolvimento de Sistemas - AEMS

Introdução a POO. Introdução a Linguagem C++ e POO

Transcrição:

Programação Concorrente na Linguagem Vale 4 por Simão Sirineo Toscani VII Simpósio Brasileiro de Linguagens de Programação SBLP 2003 Ouro Preto,, MG, Brasil Pontifícia Universidade Católica do Rio Grande do Sul PUCRS Centro Universitário La Salle UNILASALLE 0

Introdução (1) Iremos apresentar Uma linguagem de programação para uso acadêmico Construída usando software livre (SWI-Prolog) Que pode ser instalada em qualquer microcomputador Os exemplos são programas completos, prontos para serem executados. O ambiente de programação V4 É formado por um compilador uma máquina virtual Trata-se de um ambiente completo para construção e depuração de programas concorrentes. 1

Introdução (2) Programa concorrente É um programa que origina processos concorrentes (paralelos) durante sua execução. Estes processos interagem através de mecanismos apropriados, normalmente implementados no kernel do SO. A técnica da programação concorrente foi usada originalmente na construção de sistemas operacionais. Hoje em dia seu uso está difundido em todas as áreas. 2

Motivação para a criação da linguagem (1) Os profissionais da computação devem dominar as técnicas e ferramentas usadas na construção de programas concorrentes. Não há uma linguagem adequada para esse tipo de ensino. O ideal seria que o estudante pudesse aprender a solucionar os problemas clássicos usando todas as ferramentas descritas na literatura. 3

Motivação para a criação da linguagem (2) Os problemas clássicos: 1. Produtor-consumidor (relação de cooperação) 2. Jantar dos filósofos (relação de competição) 3. Barbeiro dorminhoco (relação cliente-servidor) 4. Leitores e escritores (situação comum em banco de dados) As principais ferramentas: 1. Semáforos 2. Monitores 3. Operações send e receive 4. Rendezvous 4

A linguagem Vale 4 Implementa quase todas as ferramentas e paradigmas da programação concorrente Sintaxe simples(*) e semântica clara Facilidades para depuração (visualização da execução) É implementada por um compilador uma máquina virtual (*) Baseada na sintaxe livre usada nas notas de aula do autor. 5

O compilador V4 Traduçã ção o dirigida por sintaxe. O resultado da compilaçã ção é: Uma tabela de símbolos s (TS) e Um código c de máquina m virtual. 6

O simulador V4 A partir da TS, o simulador da máquina virtual gera estruturas e faz a execução do código. Estruturas de dados: Variáveis inteiras, variáveis booleanas Arrays de até duas dimensões Registros descritores de processos Filas, semáforos Filas de monitores, variáveis tipo condition Filas de espera para rendezvouz, etc. 7

O ambiente de execução V4 O compilador: repeat, letoken(x), colocanapilha(x), tratapilha until X = endprogram O simulador: gera estruturas de dados, repeat, selecionathread(t), if T>0 then executa T until T = -1, write('fim DA EXECUÇÃ ÇÃO') 8

Os tokens da linguagem V4 := : ;, ( ) [ ] { } ' + - * / mod & and or not % /* */ integer boolean init queue semaphore array procedure returns while do forever if then else loop endloop exit when inline process task thread fork join quit mutexbegin mutexend block wakeup P V yield hold monitor condition priority wait signal initially empty count first insert send receive entry accept read write nl tab debug1 debug2 nodebug pause nothing myself getid random clocktime end identificadores const_inteiras const_booleanas 9

Os comandos da linguagem Var := E A P ( Sem ) if E L then C 1 else C 2 V ( Sem ) while E L do C yield do forever C hold ( Time ) loop C 1 ; C 2 ;... ; C n endloop wait ( Cond ) { C 1 ; C 2 ;... ; C n } wait ( Cond, Prior ) read ( Var ) signal ( Cond ) write ( Var ) send ( ProcessId, Msg ) nl nb_send ( ProcessId, Msg ) tab ( K ) receive ( ProcessId, Msg ) nothing id := fork mutexbegin id := new Pname ( arg 1, arg 2,..., arg N ) mutexend join ( id ) lock quit unlock debug1 insert ( id, Q ) debug2 insert ( id, Q, Prior ) nodebug id := first ( Q ) pause block exec ( Nome ) wakeup ( id ) (Total de 40 accept Et ( arg 1 :T 1 ; arg 2 :T 2 ;... ; arg N :T N ) returns T when E L do C comandos) 10

As instruções da máquina virtual if X oprel Y goto E call NomeProc P S myself goto E [n, lista] V S getid P read X return entermonitor M clocktime write X nothing leavemonitor M random N push X yield wait C nl pop X hold wait C, Prior tab X add fork signal C debug1 sub join rndzvs Entry debug2 mult quit accept Entry nodebug div mutexbegin give_up_rndzvs pause mod mutexend send Id,Msg exec X jump E block receive Id,Msg jzer E wakeup P end proced jpos E first Q end process (Total de 62 jneg E insert P, Q end monitor instruções) jsub E is_empty Q end task ret count Q end accept 11

As versões da linguagem Didaticamente, a linguagem oferece 6 versões: V4 0 : processos, variáveis globais e procedimentos V4 1 : V4 0 com operações mutexbegin/mutexend e block/wakeup(p) V4 2 : V4 0 com semáforos V4 3 : V4 0 com monitores V4 4 : processos com operações send/receive V4 5 : tasks com threads e rendezvous. 12

Formas de criar processos Especificação de processos individuais Especificação de array de processos Especificação de modelo (template) de processo (Nos dois primeiros casos, a criação é estática) 13

Especificação de processos (1) % Especificação individual V4program process p; k: integer init 0; while k < 10 do { write(1); k:= k+1 }; process q; k: integer init 0; while k < 10 do { write(2); k:= k+1 } endprogram 14

Especificação de processos (2) % Array de processos V4program process p(i:= 1 to 2); k: integer init 0; while k < 10 do { write(i); k:= k+1 } endprogram 15

Especificação de processos (3) % Modelo de processo V4program process type p(i: integer); k: integer init 0; while k < 10 do { write(i); k:= k+1 }; process qqnome; { new p(1); new p(2) } endprogram 16

Uso de um procedimento % Especificação individual e uso de procedimento V4program procedure imprime(n: integer); k: integer init 0; while k < 10 do { write(n); k:= k+1 }; process p; imprime(1); process q; imprime(2) endprogram 17

Código gerado para o programa anterior ============== TABELA DE SIMBOLOS ============== IND NOME TIPO V_INIC AGRUP INSIDE 0 imprime routine 0 n_arg(1) global 1 n integer 0 none proced(imprime) 2 k integer 0 none proced(imprime) 3 p process 9 none global 4 q process 12 none global END CÓDIGO GERADO 0 [if,#(2),<,$10,goto,2] 1 [return] 2 [write, #(1)] 3 [push, #(2)] 9 [call, imprime] 4 [push, $1] 10 [1, 1] 5 [add] 11 [end, process] 6 [pop, #(2)] 12 [call, imprime] 7 [goto, 0] 13 [1, 2] 8 [end, proced] 14 [end, process] 18

O mesmo programa anterior % A identificação única (pid) V4program procedure imprime(n: integer); k: integer init 0; while k < 10 do { write(n); k:= k+1 }; process p; imprime(myself); process q; imprime(myself) endprogram 19

Ainda o mesmo programa % Criação de threads % (qual o resulado da execução?) V4program process p; k, id: integer init 0; { id:= fork(); while k < 10 do { write(myself); k:= k+1 } } endprogram 20

Grafo de fluxo de processos com block/wakeup wakeup(p) V4program process P1; { nl; write('p1'); wakeup(p3); wakeup(p4); quit }; process P2; { nl; write('p2'); wakeup(p5); quit }; process P3; { block; nl; write('p3'); wakeup(p5); quit }; process P4; { block; nl; write('p4'); wakeup(p5); quit }; process P5; { block; block; block; nl; write('p5'); quit } endprogram p3 I p1 p2 p4 p5 F 21

Grafo de fluxo de processos com threads V4program process p; k2, k4 : integer; { k2:= fork; if myself = k2 then {nl; write('p2'); quit}; nl; write('p1'); k4:= fork; if myself = k4 then {nl; write('p4'); quit}; nl; write('p3'); join(k2); join(k4); nl; write('p5') } endprogram p3 I p1 p2 p4 p5 F 22

Variáveis semáforas São variáveis especiais, sobre as quais só podem ser aplicadas duas operações: P e V (Proberen e Verhogen). Um semáforo é implementado por um contador (variável inteira) e uma fila de espera. Sendo S um semáforo, as operações P e V funcionam da seguinte maneira: P(S): Testa o contador de S; se é zero, coloca o processo na fila de espera (bloqueia o processo); caso contrário decrementa o contador de 1. V(S): Testa a fila de S; se está vazia, incrementa o contador de 1; caso contrário libera (desbloqueia) o primeiro processo da fila de espera. 23

Grafo de fluxo de processos com semáforos V4program S3, S4, S5: semaphore initial 0; process P1; { nl; write('p1'); V(S3); V(S4) }; process P2; { nl; write('p2'); V(S5) }; process P3; { P(S3); nl; write('p3'); V(S5) }; process P4; { P(S4); ; nl; write('p4'); V(S5) }; process P5; { P(S5); P(S5); P(S5); nl; write('p5') } endprogram p3 I p1 p2 p4 p5 F 24

O jantar dos filósofos com semáforos garfo 3 filósofo 4 garfo 4 filósofo 5 filósofo 3 spaghetti garfo 5 garfo 2 filósofo 2 garfo 1 filósofo 1 V4program garfo : array[5] of semaphore init 1; process filosofo(i:= 1 to 5); j, k, t: integer; while k =< 10 do { if i = 1 then { P(garfo[5]); P(garfo[1])} else {j:= i-1; P(garfo[j]); P(garfo[i])}; nl; write('filosofo '); write(i); write(' comecou a comer'); t:=random(5); hold(t); if i=1 then { V(garfo[5]); V(garfo[1])} else {j := i-1 ; P(garfo[j]); P(garfo[i])}; nl; write('filosofo '); write(i); write(' parou de comer'); k:=k+1 } endprogram 25

Formato de um monitor monitor <nome>; --------------------------------------------------------------------------------------- Declaração dos dados compartilhados pelos processos. Exemplo: X, Y: integer C, D: condition; ---------------------------------------------------------------------------------------- procedure P(arg 1 : T 1,...,arg P : T P ); Declaração das variáveis locais de P; {... wait(d);... }; procedure Q(arg 1 : T 1,...,arg Q : T Q ); Declaração das variáveis locais de Q; {... signal(c);... }; initially {Comandos} % inicialização dos dados (opcional) end <nome>; 26

O jantar dos filósofos com monitores V4program monitor garfos; glivre: array[5] of integer init 2; ok: array[5] of condition; procedure pega(i:integer); j: integer; k: integer; { if glivre[i] < 2 then wait(ok[i]); j := i-1; if j=0 then j:=5; glivre[j]:= glivre[j]-1; k := i+1; if k=6 then k:=1; glivre[k]:=glivre[k]-1 }; procedure libera(i:integer); j: integer; k: integer; { j := i-1; if j=0 then j:=5; glivre[j]:= glivre[j]+1; k := i+1; if k=6 then k:=1; glivre[k]:=glivre[k]+1; if glivre[j] = 2 then signal(ok[j]); if glivre[k] = 2 then signal(ok[k]) } end monitor; process filosofo(i:=1 to 5); k, t: integer init 0; while k =< 10 do { garfos.pega(i); nl; write('filos '); write(i); write(' comendo t:= random(5); hold(t); % come 0-4 u.t garfos.libera(i); nl; write('filos '); write(i); write(' pensando t:= random(5)+6; hold(t); % pensa 6-10 u k:= k+1 } endprogram 27

Alocação de um recurso de N unidades V4program monitor resource; N: integer init 10; % 10 unidades C: condition; procedure requisita(k: integer); { loop if k =< N then exit; wait(c) endloop; N := N-k; signal(c) }; procedure libera(k: integer); { N := N+k; signal(c) } end resource; process cliente(i:=1 to 10); { resource.requisita(i); nl; write('cliente '); write(i); resource.libera(i) } endprogram O que acontece se, no procedimento requisita, o signal(c) é colocado logo após o wait(c)? 28

Formato de uma task task nome is declaração de variáveis; declaração de entries; declaração de procedures; thread main is { C1; C2; ; Cn } end nome Formato do comando accept: accept Et (arg 1 :T 1 ; arg 2 :T 2 ;... ; arg N :T N ) returns T when expressão_lógica do { C1; C2; ; Cn } 29

Alocação de um recurso de N unidades V4program task resource is entry requisita(k: integer); entry libera(k: integer); id: integer; N: integer init 10; % recurso tem 10 unidades thread main is { id:= fork; if id = myself then loop % --- thread filha accept requisita(k: integer) when k <= N do N:= N-k endloop else loop % --- thread mãe accept libera(k: integer) do N:= N+k endloop } end resource; process cliente(i:=1 to 10); { resource.requisita(i); nl; write('cliente '); write(i); resource.libera(i) } endprogram 30

As operações send e receive send(p, msg) receive(q, msg) receive(any any, msg) nb_send send(p, msg) 31

Comunicação via fork, join e quit id:= fork quit join(id) quit(valor) var:= join(id) var:= join(any any) 32

As facilidades de depuração debug1 debug2 nodebug exec(nome) pause janelas de visualizaçã ção 33

Conclusão (1) Instalação do sistema: Criar a pasta (diretório) Vale4 Fazer download do SWI-Prolog (programa de instalação) a partir do site: http://www.swi-prolog.org/ 3. Instalar o SWI-Prolog na pasta Vale4 (a instalação vai criar o diretório pl ) 4. Copiar os arquivos V4compiler, V4_1 e V4_2 e programas exemplos para a pasta Vale4. (O sistema é colocado em uso com dois clicks no arquivo V4compiler) 34

Conclusão (2) O sistema está operacional. Sua instalação é muito simples. V4 é uma ferramenta para treinamento (ensino/aprendizagem). Não é linguagem para produção de software (não há preocupação com geração de código otimizado, tampouco com eficiência de execução). A linguagem é usada para ilustrar o livro Programação Concorrente e Sistemas Operacionais que será lançado em breve. 35

Barbeiro dorminhoco (task( e threads) V4program task barbershop is k, t, id1, id2: integer; empty_chair: boolean; #chairs: integer initial 3; entry client_in(id: integer); procedure avail_chair() returns boolean; { mutexbegin; if #chairs > 0 then { #chairs:= #chairs-1; avail_chair:= true } else avail_chair:= false; mutexend }; thread main is { id1:= fork; if id1 = myself then loop % loop da thread barbeiro accept client_in(id: integer) do % dorme se não há cliente { nl; write('client '); write(id); write(' at time '); write(clocktime); hold(2); #chairs:= #chairs+1 } endloop; 36

Barbeiro dorminhoco (continuação) loop % thread main gera 20 clientes id2:= fork; if id2 = myself then { empty_chair:= avail_chair(); if empty_chair then client_in(id2); quit }; t:= random(6); hold(t); % espera um tempo entre 0 e 5 u.t. (média 2.5) k:= k+1; exit when k=20 endloop } end barbershop end program 37

Busca do elemento máximo de um vetor por divisão e conquista V4program task xmax is vet: array[10] of integer; Imax: integer init 0; % Índice do maior elemento do vetor procedure getmax(i:integer; j:integer) returns integer; dif, m, m1, id1, id2, max1, max2: integer; { dif:=j-i; if dif=0 then getmax:=i elseifdif=1thenifvet[i]>vet[j] then getmax:=i else getmax:=j else { m:=(i+j)/2; m1:=m+1; id1:=fork; if id1=myself then {max1:=getmax(i,m); quit}; id2:=fork; if id2=myself then {max2:=getmax(m1,j);quit}; join(id1); join(id2); if vet[max1] > vet[max2] then getmax:=max1 else getmax:=max2 } }; thread main is { vet[1]:=1; vet[2]:=10; vet[3]:=3; vet[4]:=100; vet[5]:=2; Imax:=getmax(1,5); nl; write('vobtido = '); write(vet[imax]) } end xmax end program 38

Monitor para o problema dos readers & writers monitor ReadersAndWriters; #readers: integer initial 0; activewriter: boolean initial false; oktoread, oktowrite: condition; procedure startread(); { if activewriter or empty(oktowrite) then wait(oktoread); #readers:=#readers+1; signal(oktoread) }; procedure endread(); { #readers:=#readers-1; if #readers=0 then signal(oktowrite) }; procedure startwrite(); { if #readers>0 or activewriter then wait(oktowrite); activewriter:=true }; procedure endwrite(); { activewriter:=false; if empty(oktoread) then signal(oktoread) else signal(oktowrite) } end ReadersAndWriters; 39

Produtores-consumidores com semáforos V4program buffer: array[2] of integer init 0; cheios: semaphore init 0; vazios: semaphore init 2; mutex : semaphore init 1; in,out: integer init 1; process produtor(i:=0 to 1); nextpar: integer init 0; nextimpar: integer init 1; while nextimpar < 20 & nextpar < 20 do { P(vazios) ; P(mutex); if i = 0 then { nextpar:= nextpar + 2; buffer[in]:= nextpar } else { nextimpar:= nextimpar + 2; buffer[in]:= nextimpar }; in:=(in mod 2)+1; V(mutex); V(cheios) }; process consumidor(i:=1 to 2); msg: integer; do forever { P(cheios); P(mutex); msg:= buffer[out]; out:=(out mod 2)+1; V(mutex); V(vazios); nl; if i = 2 then tab(10); write(msg) } endprogram 40