Mapeamento de CSP para JCSP Patrícia Muniz (pmf) Rafael Duarte (rmd)
Transcript of Mapeamento de CSP para JCSP Patrícia Muniz (pmf) Rafael Duarte (rmd)
Mapeamento de CSP para JCSPMapeamento de CSP para JCSP
Patrícia Muniz (pmf)
Rafael Duarte (rmd)
Revisão JCSP
• Um processo é um objeto de uma classe que implementa:
• O comportamento do processo é determinado pelo corpo do método run()
interface CSProcess { public void run(); }
interface CSProcess { public void run(); }
Revisão JCSP
• Um canal é um objeto de uma classe que implementa:
interface Channel { } interface Channel { }
Revisão JCSP
• Já vimos interfaces e classes JCSP que implementam:– Processos– Canais– Paralelismo– Composição sequencial
• Falta apresentar escolha (Alternative)
Alternative
– Implementa (external) choice– Exemplo:
AltingChannelInput ch1, ch2 = ...Guard[] guards = new Guard[] {ch1, ch2}; boolean[] preconditions = new boolean[] {g1, g2};
Alternative alt = new Alternative(guards);int indexGuard = alt.select(preconditions);
AltingChannelInput ch1, ch2 = ...Guard[] guards = new Guard[] {ch1, ch2}; boolean[] preconditions = new boolean[] {g1, g2};
Alternative alt = new Alternative(guards);int indexGuard = alt.select(preconditions);
algoritmo de seleção
Canais em JCSP
Alternative
• Uma guarda pode ser apenas um evento de entrada, ou um timeout, ou o processo Skip
Sempre ativo
Torna-se ativo quando o timeoutdispara
Torna-se ativo quando chega um sinal
Torna-se ativo quando umachamada demétodo pode serexecutada
Alternative
• Canais One2Any e Any2Any não podem ser usados como guardas, porque podem gerar inconsistências
One2AnyChannel a;a.out().write(...);One2AnyChannel a;a.out().write(...);
One2AnyChannel a;alt = new Alternative(a.in());switch (alt.select())case 0:
a.in().read();
One2AnyChannel a;alt = new Alternative(a.in());switch (alt.select())case 0:
a.in().read();
One2AnyChannel a;a.in().read();One2AnyChannel a;a.in().read();
O evento aa foi selecionado porque está ativo, embora tenha sido direcionado para outro processo
Não compila! SharedChannelInput não é do tipo Guard
Mapeamento de canais• One2OneChannel a = P(a.out()) [|a|] Q(a.in())
• One2AnyChannel a = P(a.out()) [|a|] (Q1(a.in()) ||| Q2(a.in()))
• Any2OneChannel a = (P1(a.out()) ||| P2(a.out())) [|a|] Q(a.in())
• Any2AnyChannel a = (P1(a.out()) ||| P2(a.out())) [|a|] (Q1(a.in()) ||| Q2(a.in()))
Na prática a comunicação é sempre ponto-a-ponto, porque apenas 2 processos se comunicam por vez
Mapeamento de processos
• O que temos em CSP?1. P = pre & a -> P2. P = a?x:{restricao} -> P3. P = a!x?y -> P4. P = (a -> P) [] (b -> P)5. P = (a -> P) |~| (b -> P)6. P = a -> Q7. P = (a -> Q) [] (b -> R)8. P = Q ||| R9. P = Q || R10. P = Q |a| R11. ....
CUIDADOJCSP não possui mecanismos naturais para algumas destas construções!
Mapeamento de processos
1. P = pre & a -> P
P implements CSProcess {AltingChannelInput a;public void run() {
boolean pre = ...Guard[] guards = new Guard[]{a};bollean[] preconditions = new boolean[] {pre};Alternative alt = new Alternative(guards);
while (true) {switch (alt.select(preconditions))case 0:
a.read();break;
}}
}
P implements CSProcess {AltingChannelInput a;public void run() {
boolean pre = ...Guard[] guards = new Guard[]{a};bollean[] preconditions = new boolean[] {pre};Alternative alt = new Alternative(guards);
while (true) {switch (alt.select(preconditions))case 0:
a.read();break;
}}
}
Mapeamento de processos
2. P = a?x:{restricao} -> P
A restrição de um valor de entrada pode ser verificada apenas após a leitura do dado.
Mas neste ponto já houve sincronização!! Se o canal for de saída (ChannelOutput), a
restrição pode ser implementadaif (f_restricao(x)) {
a.write(x);}
Mapeamento de processos
3. P = a!x?y -> P
Há várias formas de implementar canais com múltiplos dados
Atenção para troca mútua de dados: P(e) = a?x!e -> P(e)Q(e) = a!x?e -> Q(e)
Mapeamento de processos
3.1 P = a!x?y -> PP = a!x?y -> ... // um canal para cada dadoQ = a?x!y -> ...
P { ChannelOutput ax;AltingChannelInput ay;...ax.write(valueX);DataY valueY = (DataY)ay.read();...
}Q { AltingChannelInput ax;
ChannelOutput ay;...DataX valueX = (DataX)ax.read();ay.write(valueY);...
}
P = a!x?y -> ... // um canal para cada dadoQ = a?x!y -> ...
P { ChannelOutput ax;AltingChannelInput ay;...ax.write(valueX);DataY valueY = (DataY)ay.read();...
}Q { AltingChannelInput ax;
ChannelOutput ay;...DataX valueX = (DataX)ax.read();ay.write(valueY);...
}
Mapeamento de processos
4. P = (a -> P) [] (b -> P)
Os canais de entrada são naturalmente usados como Guard
Canais de saída não podem ser usados como Guard
– opção 1: criar um novo canal de entrada e antecedê-lo ao canal de saída
b!out -> .... user -> b!out -> ...
– opção 2: usar um timeout antes da ocorrência do canal de saída
Mapeamento de processos
4. P = (a!x -> P) [] (b?y -> P)P implements CSProcess {
AltingChannelInput b, user;OutputChannel a;public void run() {
Guard[] guards = new Guard[]{b, user};Alternative alt = new Alternative(guards);
while (true) {switch (alt.select())case 0: b.read();
break; case 1: user.read();
a.write(..);break;
}}
}
P implements CSProcess {AltingChannelInput b, user;OutputChannel a;public void run() {
Guard[] guards = new Guard[]{b, user};Alternative alt = new Alternative(guards);
while (true) {switch (alt.select())case 0: b.read();
break; case 1: user.read();
a.write(..);break;
}}
}
Mapeamento de processos
5. P = (a -> P) |~| (b -> P)
Noção pouco clara O não-determinismo pode ser implementado através
do método de seleção de Alternativeselect() – seleciona arbitrariamente na lista de guardas ativas
priSelect() – seleciona o primeiro da lista de guardas ativas
fairSelect() – seleciona a guarda ativa menos visitada
Mapeamento de processos
6. P = a -> Q
P = a -> Skip; Q
P implements CSProcess {ChannelInput a;public void run() {
a.read();new Q().run();
}}
P implements CSProcess {ChannelInput a;public void run() {
a.read();new Q().run();
}}
new Sequence( new CSProcess[] {new PSkip(..), new Q(...)
} )
new Sequence( new CSProcess[] {new PSkip(..), new Q(...)
} )
Mapeamento de processos
6. P = a -> Q Atenção para a passagem de parâmetros
P(x) = ... -> Q(f(x)) onde definir f(x)?
P implements CSProcess {Object x;public void run() {
...new Q( f(x) ).run();
}}
P implements CSProcess {Object x;public void run() {
...new Q( f(x) ).run();
}}
Mapeamento de processos
7. P = (a -> Q) [] (b -> R)
P implements CSProcess {AltingChannelInput a, b;public void run() {
Guard[] guards = new Guard[]{a, b};Alternative alt = new Alternative(guards);
switch (alt.select())case 0: a.read();
new Q().run(); break;
case 1: b.read();new R().run();break;
}}
P implements CSProcess {AltingChannelInput a, b;public void run() {
Guard[] guards = new Guard[]{a, b};Alternative alt = new Alternative(guards);
switch (alt.select())case 0: a.read();
new Q().run(); break;
case 1: b.read();new R().run();break;
}}
Mapeamento de processos
8. P = Q ||| R Canais Any2One, One2Any e Any2Any
class Q implements CSProcess {
ChannelInput a;
ChannelOutput b;
a.in().read();
...
b.out().write(...); }
class Q implements CSProcess {
ChannelInput a;
ChannelOutput b;
a.in().read();
...
b.out().write(...); }
class Exemplo { Any2OneChannel a = Channel.any2one(); One2AnyChannel b = Channel.one2any(); public void run(){ new Parallel (new CSProcess[] { new Q(a.out(),b.in()),//b.in()!=b.in() // a.out() SharedChannelOutoput new Q(a.out(),b.in()), //b.in() SharredChannelInput new CSProcess () { public void run () { a.out().write(1); b.in().read();} } }).run (); }}
class Exemplo { Any2OneChannel a = Channel.any2one(); One2AnyChannel b = Channel.one2any(); public void run(){ new Parallel (new CSProcess[] { new Q(a.out(),b.in()),//b.in()!=b.in() // a.out() SharedChannelOutoput new Q(a.out(),b.in()), //b.in() SharredChannelInput new CSProcess () { public void run () { a.out().write(1); b.in().read();} } }).run (); }}
Mapeamento de processos
9. P = Q || R e 10. P = Q |a| R Canais One2One devem ser usados para garantir
a sincronização ponto-a-ponto Os demais tipos de canais (One2Any, Any2One,
Any2Any) não garantem comunicação síncrona entre todos os participantes.
A sincronização é alcançada pelo uso da referência ao mesmo canal em Q e R
Mapeamento de processos
9. P = Q || R e 10. P = Q |a| R Para cada 2 processos em paralelo é usado 1
canal One2One para cada evento de sincronização
// Q |a| ROne2OneChannel a = Channel.one2one(); public void run(){ new Parallel (new CSProcess[] { new Q(a.in()), new R(a.out()) }).run (); }
// Q |a| ROne2OneChannel a = Channel.one2one(); public void run(){ new Parallel (new CSProcess[] { new Q(a.in()), new R(a.out()) }).run (); }
Mapeamento de processos
9. P = Q || R e 10. P = Q |a| R Para 3 ou mais processos em paralelo é usado
um array de canais One2One para cada evento de sincronização
// (Q |a| R) |a| SOne2OneChannel[] a = Channel.one2oneArray(3);
new Parallel ( new Parallel (new CSProcess[] { new Q_11(a[1].in(),a[2].out()), new R_11(a[2].in(),a[0].out()), new S_11(a[0].in(),a[1].out()) } ).run();
// (Q |a| R) |a| SOne2OneChannel[] a = Channel.one2oneArray(3);
new Parallel ( new Parallel (new CSProcess[] { new Q_11(a[1].in(),a[2].out()), new R_11(a[2].in(),a[0].out()), new S_11(a[0].in(),a[1].out()) } ).run();
Outras construções de JCSP
• Barriers– Enquanto um Channel pode sincronizar apenas 2
processos por vez (reader e writer), Barriers podem sincronizar qualquer número definido de processos
– Executam eventos que não transmitem qualquer informação, mas que bloqueiam processos até que todos possam sincronizar
– Não podem ser guardas de um Alternative
barrier
P P P
Exemplo
final Barrier barrier = new Barrier (nPlayers);for (int i = 0; i < players.length; i++) { players[i] = new Player (i, nPlayers, barrier);}....
public void run(){System.out.println ("Player " + id + " at the barrier ..."); barrier.sync (); System.out.println ("\t\t\t... Player " + id + " over the barrier");}
final Barrier barrier = new Barrier (nPlayers);for (int i = 0; i < players.length; i++) { players[i] = new Player (i, nPlayers, barrier);}....
public void run(){System.out.println ("Player " + id + " at the barrier ..."); barrier.sync (); System.out.println ("\t\t\t... Player " + id + " over the barrier");}
Outras construções de JCSP
• Buckets– Executam eventos que não transmitem qualquer
informação, mas que bloqueiam processos até que seu método flush() seja executado
– São não-determinísticos, desde que a decisão para executar o flush() é uma escolha interna do processo responsável
bucket
P P P
Flusher
flush()
Exercício• Implementar em JCSP os seguintes processos:
VM(c,t) = c > 0 & coffee -> VM(c-1,t) [] t > 0 & tea -> VM(c,t-1)
CLIENT = coffee -> CLIENT |~| tea -> CLIENT
SYSTEM = VM(10,10) [|{|coffee, tea|}|] CLIENT
Exemplos: www.cin.ufpe.br/~pmf/jcspwww.cin.ufpe.br/~rmd/esd/
Lembrete:Documentação mais atual:
http://www.cs.kent.ac.uk/projects/ofa/jcsp/jcsp1-0-rc7/jcsp-docs/