Introdução a JCSP
Augusto Sampaio (acas)
Patrícia Muniz (pmf)
Rafael Duarte (rmd)
Antes de JCSP ...

Implementação pode ser realizada em
outra plataforma
•
•
•
•

UML-RT
CTJ (Biblioteca semelhante a JCSP)
occam (“implementação” de CSP)
...
Mas o curso inclui apresentação
apenas de JCSP e UML-RT
JCSP - Características gerais




Biblioteca Java que implementa o modelo
de comunicação e concorrência de
CSP/occam (com restrições)
Suporta o projeto orientado a processos
Implementação com base no mecanismo
de threads/monitor de Java
Versões
• Base Edition
• Network Edition (suporte a distribuição)
JCSP - Características gerais

Elementos de CSP disponíveis
•
•
•
•
•

Canais
Comunicação (também com buffer e multi)
Composição seqüencial
Paralelismo (não alfabetizado)
Escolha externa (com restrições e
extensões)
Alguns operadores não implementados
• Hiding, interrupção, paralelismo
alfabetizado, indexação, ...
Processos em JCSP ...


Um processo é uma entidade autônoma
(fluxo de execução independente)
Encapsula estado (atributos) e métodos
• Construtores são públicos


Comunicação com o ambiente via canais
(como em CSP ou como cápsulas UML-RT)
Comportamento ativo (fluxo)
implementado pelo método run()
(público)
Processos em JCSP ...

Um processo é um objeto de uma classe
que implementa a interface CSProcess
interface CSProcess {
public void run();
}

Toda classe que implementa
CSProcess deve prover uma
implementação de run()
Estrutura de um processo
class Example implements CSProcess {
...
...
}
private shared synchronisation objects
(channels etc.)
private state information
...
...
public constructors
public accessors(gets)/mutators(sets)
(only to be used when not running)
...
...
private support methods (part of a run)
public void run() (process starts here)
Canais em JCSP ...

Um canal é um objeto de uma classe que
implementa uma das interfaces:
•
•
•
•
ChannelInput
ChannelOutput
ChannelInputInt
ChannelOutputInt
Canais em JCSP


Um canal carrega algum tipo de
informação
Canais podem levar informação a um
processo (output channels), ou trazer
informação de um processo (input
channels)
Processos e canais

Quando um processo dispara um
evento através de um canal, permanece
bloqueado até que seu receptor
responda
class P implements CSProcess{
ChannelOutput a;
public void run() {
a.write(...);
}
}
class Q implements CSProcess{
ChannelInput a;
public void run() {
x = a.read();
}
}
Interfaces para canais de
inteiros e objetos
interface ChannelOutput {
public void write (Object o);
}
interface ChannelOutputInt {
public void write (int o);
}
interface ChannelInput {
public Object read ();
}
interface ChannelInputInt {
public int read ();
}
One2OneChannel
Any2OneChannel
One2AnyChannel
Any2AnyChannel
Canais em JCSP
Canais de objetos …



Como default, canais são (fully
synchronised).
JCSP oferece um conjunto de plugins de
canais que fornece uma variedade de tipos
de bufferização (FIFO blocking,
overflowing, overwriting, infinite)
Ver jcsp.util.
Exemplo
in
SuccInt
out
class SuccInt implements CSProcess {
private final ChannelInputInt in;
private final ChannelOutputInt out;
public SuccInt (ChannelInputInt in,
ChannelOutputInt out) {
this.in = in;
this.out = out;
}
public void run () {
while (true) {
int n = in.read ();
out.write (n + 1);
}
}
}
Exemplo
in0
in1
+
out
class PlusInt implements CSProcess {
private final ChannelInputInt in0;
private final ChannelInputInt in1;
private final ChannelOutputInt out;
public PlusInt (ChannelInputInt in0,
ChannelInputInt in1,
ChannelOutputInt out) {
this.in0 = in0;
this.in1 = in1;
this.out = out;
}
...
}
public void run ()
Exemplo
in0
in1
+
out
class PlusInt implements CSProcess {
...
private final channels (in0, in1, out)
...
public PlusInt (ChannelInputInt in0, ...)
public void run () {
while (true) {
int n0 = in0.read ();
int n1 = in1.read ();
out.write (n0 + n1);
}
}
}
seqüencial
Redes de processos

Instâncias de processos (componentes)
podem ser combinadas para formar uma
rede



A rede resultante é também um processo
Componentes são interligados via
conectores (instâncias dos canais)
Os componentes executam em paralelo,
como em um diagrama de estrutura UMLRT
A classe Parallel



Parallel é um CSProcess cujo construtor
tem como argumento um array de processos
O método run() implementa a composição
paralela dos processos argumentos
A semântica é a mesma do operador de CSP
|| [Hoare]: o método run() termina apenas
quando todos os argumentos finalizam com
sucesso
Exemplo
in0
in1
+
out
em paralelo dos
argumentos de
entrada Leitura
public void run () {
ProcessReadInt readIn0 = new ProcessReadInt (in0);
ProcessReadInt readIn1 = new ProcessReadInt (in1);
CSProcess parRead =
new Parallel (new CSProcess[] {readIn0, readIn1});
while (true) {
parRead.run ();
out.write (readIn0.value + readIn1.value);
}
}
Mais sobre a classe Parallel



Oferece métodos para adicionar
(addProcess) e remover processos
(removeProcess)
Entretanto, estes métodos só devem
ser invocados quando o objeto não
está em execução (método run())
Se invocados durante a execução, o
efeito só ocorrerá após o final da
mesma
Detalhes de implementação




Um objeto JCSP Parallel executa os
primeiros (n-1) componentes em threads
separadas e o último componente na sua própria
thread de controle.
Quando Parallel.run() termina, o objeto
Parallel guarda todas as threads para reuso,
caso o Parallel execute novamente
Processos como PlusInt geram o overhead de
criação de threads apenas a primeira vez
Portanto, definir parRead fora do loop, ao
invés de construí-lo anonimamente em cada
iteração tem forte impacto em eficiência
Exercício

Implemente em JCSP o processo Main
Send (i) = chan ! i -> Send (i+1)
Read = chan ? x -> Print(x); Read
Print(x) = ...
Main = Send (0) || Read
Exercício 1 – processo Send
public class Send {
private final ChannelOutputInt chan;
private int i;
public Send(ChannelOutputInt chan, int i) {
this.chan = chan;
this.i = i;
}
public void run() {
while (true) {
chan.write(i);
i = i + 1;
}
}
}
Exercício – processo Read
public class Read {
private final ChannelInputInt chan;
public Read(ChannelInputInt chan) {
this.chan = chan;
}
public void run() {
while (true) {
int i = chan.read();
System.out.println(i);
}
}
}
Exercício – processo Main
public class ExampleMain {
public static void main (String[] args) {
One2OneChannelInt chan =
new One2OneChannelInt();
Send send = new Send(chan);
Read read = new Read (chan);
CSProcess[] parArray = {send,read};
Parallel par = new Parallel (parArray);
par.run();
}
}
Exercício 2 – Comunicação Assíncrona
public class ExampleMain {
public static void main (String[] argv) {
One2OneChannelInt chan1 =
new One2OneChannelInt ();
One2OneChannelInt chan2 =
new One2OneChannelInt ();
new Parallel ( new CSProcess[] {
new Send (chan1),
new IdentityInt(chan1, chan2),
new Read (chan2)} ).run ();
}
}
Send
chan1
Identity
chan2
Read
Composição seqüencial

class Sequence (implements CSProcess)
• CSProcess cujo construtor tem
como argumento um array de
processos
• O método run() implementa a
composição seqüencial dos
processos argumentos.
Leitura e Instalação

An Introduction to JCSP Base Edition (tutorial
interessante, mas versão da biblioteca não
é a mais atual)
http://www.quickstone.com/resources/jcspnetworkedition/IntroductionToJCSP.pdf

Versão mais atual
http://www.cs.kent.ac.uk/projects/ofa/jcsp/jcsp1-0-rc7/jcsp-docs/

Instalação
http://www.cs.kent.ac.uk/projects/ofa/jcsp/
Download

public void run