csp

advertisement
Communicating Sequential
Processes
Based on:
C. A. R. Hoare, Communicating Sequential Processes, CACM,
21(8):666-677, November, 1978.
1
Outline
• Background and motivation
• Concepts and notation
• Examples
2
Background
• Imperative programming models
– Commands: assignment, sequence,
alternative, iterative
– I/O as library functions, not primitive
• Concurrency and parallelism
– Multi-processor disguised as mono-processor
– Need for expressing concurrency explicitly
– Shared memory vs. message passing
3
Motivation
• New programming model based on message
passing
• I/O regarded as primitive constructs
• Concurrency (parallel composition of processes)
as fundamental structuring method
=>
• Concurrent Sequential Processes (CSP)
4
Key Features of CSP
• Dijkstra’s guarded commands
– [B1 -> S1 [] B2 -> S2 ]
– For introducing and controlling non-determinism (or choice)
• Dijkstra’s parallel commands
– [P1 || P2]
– For concurrency
• Input and output commands
– p?x; q!x
– For receiving and sending messages
• Input commands in guards and repetitive commands
– [p?x -> S]; *[p?x -> S]
– Branching or repetition based on inputs
• Simple pattern matching
– For discriminating the structures of input messages and
– For accessing their components
5
Example
• Q: What does the process X do?
X:: *[c: character; west?c 
[c  asterisk  east!c
[] c  asterisk  west?c;
[c  asterisk  east!asterisk; east!c
c  asterisk  east!up_arrow
]
]
]
6
Outline
 Background and motivation
• Concepts and notation
– Basic and structured statements
• Examples
7
Concepts and Notation
• Commands
–
–
–
–
Specify behavior of device executing the commands
May have side effect (internal or external)
May succeed or fail (“strict” for structured commands)
Basic vs. structured
• Basic: null (skip), assignment, input, output
• Structured: alternative, repetitive, parallel
<command> ::= <simple command> | <structured command>
<simple command> ::= <null command> | <assignment command>
| <input command> | <output command>
<structured command> ::= <alternative command>
| <repetitive command> | <parallel command>
<null command> ::= skip
<command list> :: {<declaration>; <command>;} <command>
8
Parallel Commands (||)
• List of processes separated by ||
– Process: sequence of commands preceded by an optional label
– E.g., [stdin?line || stdout!“hello”]
• Semantics
– Concurrent execution of constituent processes
– All processes start simultaneously
– Terminate successfully if all terminate successfully
<parallel command> ::= [<process> { || <process>}]
<process> ::= <process label> <command list>
9
Process
•
•
Unit of program in CSP
Sequence of commands with an optional label (Q: Why label?)
– E.g., skip, X:: skip
•
Subscripted label to specify a series of concurrently running processes
– E.g., X(1):: skip, X(i):: skip, X(i,j):: skip, X(i: 0..99):: skip
– Semantics: X(i: 1..n)::CL for
[X(1):: CL1 || X(2):: CL2 || … || X(n):: CLn]
I.e., CLj is CL[j/i]
<process> ::= <process label> <command list>
<process lablel> ::= <empty> | <identifier> ::
| <identifier>(<label subscript> {, <label subscript>}) ::
<label subscript> ::= <integer constant> | <range>
<integer constant> ::= <numeral> | <bound variable>
<bound variable> ::= <identifier>
<range> ::= <bound variable>:<lower bound>..<upper bound>
<lower bound> ::= <integer constant>
<upper bound> ::= <integer constant>
10
Example
[cardreader?cardImage || lineprinter! lineimage]
[west:: DISASSEMBLE
|| X:: SQUASH
|| east:: ASSEMBLE]
Convention: Capitalized words for process definitions
[room:: ROOM || fork(i: 0..4):: FORK || phil(i: 0..4):: PHIL]
Q: How many concurrent processes?
11
Assignment
• Simple vs. structured value
– 0, true, 10 + y, x + y, …
– (10, 20), (x, y), point(10, 20), done()
c(e1, e2, …, en)
• Signal: structured value with no component
• Q: Why structured values?
<assignment command> ::= <target variable> := <expression>
<expression> ::= <simple expression> | <structured expression>
<structured expression> ::= <constructor>(<expression list>)
<constructor> ::= <identifier> | <empty>
<expression list> ::= <empty> | <expression> {, <expression>}
<target variable> ::= <simple variable> | <structured target>
<structured target> ::= <constructor>(<target variable list>)
<target variable list> ::= <empty> | <target variable> {, <target variable>}
12
Matching Assignment
x := e
c(x1, x2, …, xn) := c(e1, e2, …, en)
• Fails if the value of expression is undefined or if that
value doesn’t match the target variable
• A simple target variable matches any value of its type.
• A structured target variable matches a structured value if
– they have the same constructor
– they have the same number of components
– Each component matches the corresponding component
13
Example
1. x := x + 1
2. (x, y) := (y, x)
3. x := cons(left, right)
4. cons(left, right) := x
Q: Match? Differ from 3?
5. insert(n) := insert(2*x + 10)
6. x := P()
7. P() := x
Q: Match?
8. insert(n) := has(n)
Q: Match?
14
Input and Output Commands
•
•
Specify communication between two CSPs, say P1 and P2, e.g.,
[P1:: x: integer; P2?x || P2:: P1!10]
Communication occurs if I/O commands correspond:
– The source of an input command in P1 is P2.
– The destination of an output command in P2 is P1.
– The target variable of the input in P1 matches the expression of the output in P2.
•
Semantics
– Simultaneous execution of corresponding I/O commands
– Effect: similar to an assignment
<input command> ::= <source> ? <target variable>
<output command> ::= <destination> ! <expression>
<source> ::= <process name>
<destination> ::= <process name>
<process name> ::= <identifier> | <identifier> ( <subscripts> )
<subscripts> ::= <integer expression> {, <integer expression>}
15
Example
1. cardreader?cardimage
2. lineprinter!lineimage
3. X?(x, y)
4. DIV!(3*a + b, 13)
5. console(i)?c
Q: if 3 and 4 correspond?
6. console(j - 1)!“A”
7. X(i)?V()
8. sem!P()
16
Alternative Commands
• Specify execution of exactly one of its constituent guarded
commands, e.g.,
[x  y  m := x [] y  x  m := y]
• Guarded commands with ranges
(i:1..n)G  CL stands for G1  CL1 [] G2  CL2 [] … [] Gn  CLn
• Multiple guard elements with an optional input command at the end
[x > 0; y: integer; user?y  user!(y/x)]
<alternative command> ::= [<guarded command> {[] <guarded command>}]
<guarded command> ::= <guard> -> <command list>
| (<range>{,<range>})<guard> -> <command list>
<guard> ::= <guard list> | <guard list>; <input command> | <input command>
<guard list> ::= <guard element> {; <guard element>}
<guard element> ::= <boolean expression> | <declaration>
17
Exercise
• Write a process that reads a number from
a user and returns its sign, i.e., -1 for
negative, 0 for 0, and 1 for positive.
• Write a process that reads three numbers
from a user and returns them sorted in
ascending order.
18
Repetitive Commands
•
•
Specify as many iterations as possible of its constituent alternative
command.
Terminate with no effect when all guards fails.
i: integer; i := 0; *[i < size; content(i)  n  i := i + 1]
*[c: character; west?c  east!c]
*[(i:1..10)continue(i); console(i)?c 
X!(i, c); console(i)!ack(); continue(i) := (c  sign_off)]
*[n: integer; X?insert(n)  INSERT
[] n: integer; X?has(n)  SEARCH; X!(i < size)]
*[X?V()  val := val + 1 [] val > 0; Y?P()  val := val – 1]
<repetitative command> := *<alternative command>
19
Exercise
• Write a process that finds a maximum
value of an array.
• Write a process that performs a binary
search on a sorted array.
20
Example: Coroutines
Read a sequence of cards of 80 characters each, and print the characters on a
line printer a 125 characters per line. Each card should be followed by an
extra space, and the last line should be completed with spaces if necessary.
[west:: DISASSEMBLE || X:: COPY || east:: ASSEMBLE]
*[cardimage: (1..80)character; cardfile?cardimage 
i: integer; i:= 1; *[i  80  X!cardimage(i); i := i + 1]; X!space]
*[c: character; west?c  east!c]
lineimage:(1..125)character;
i: integer; i := 1;
*[c: character; X?c  lineimage(i) := c;
[i  124  i := i + 1 [] i = 125  lineprinter!lineimage; i = 1]];
[i = 1  skip
[] i > 1  *[i  125  lineimage[i] := space; i := i + 1]; lineprinter!lineimage]
21
Example: Subroutines
•
Construct a process to accept a positive dividend and divisor, and to return
their integer quotient and remainder.
[DIV::
*[x, y: integer; X?(x, y) 
quot, rem: integer; quot := 0; rem := x;
*[rem  y  rem := rem – y; quot := quot + 1];
X!(quot, rem)]
•
Compute a factorial by the recursive method, to a given limit.
[fact(i:1..limit)::
*[n: integer; fact(i - 1)?n 
[n = 0  fact(i - 1)!1
[] n > 0  fact(i + 1)!(n – 1); r: integer; fact(i + 1)?r; fact(i - 1)!(n * r)]]
|| fact(0):: USER]
22
Example: ADT
•
Represent a set of not more than 100 integers as a process, S, which
accepts two kinds of instruction from its calling process X:
– S!insert(n): insert the integer n in the set
– S!has(n); …; S?b: query if n is included in the set
S::
content: (0..99)integer; size: integer; size := 0;
*[n: integer; X?has(n)  SEARCH; X!(i < size)
[] n: integer; X?insert(n)  SEARCH;
[i < size  skip
[] i = size; size < 100  content(size) := n; size := size + 1]]
where SEARCH is
i: integer; i := 0; *[i < size; content(i)  n  i := i + 1]
Q: What happen if attempted to insert more than 100 elements?
Q: What happen if attempted to insert a new element while the previous
insertions is still being processed?
23
Example: ADT
•
Extend the set ADT to provide a fast method of scanning all members of the
set, e.g.,
S!scan(); more: boolean; more := true;
*[more; x: integer; S?next(x)  … use x …
[] more; S?noneleft()  more := false]
Add a third guarded command to S:
…
[] X?scan()  i: integer; i := 0;
*[i < size  X!next(content(i)); i := i + 1];
X!noneleft()
24
Exercise
• Extend the set ADT to introduce two new operations
– S!remove(x)
– S!least(); …; x: integer; [S?x  … use x … [] S?noneleft()  …]
25
Exercise
• Define a bounded stack ADT by providing typical stack operations
such as push, pop, top, and isEmpty.
26
Example: ADT
• Define a set ADT by using an array of processes to achieve a high
degree of parallelism. (Idea: Each has at most one value, and
values kept as sorted.)
S(i:1..100)::
*[n: integer; S(i – 1)?has(n)  S(0)!false;
[] n: integer; S(i – 1)?insert(n) 
*[m: integer; S(i – 1)?has(m) 
[m  n  S(0)!(m = n)
[] m > n  S(i + 1)!has(m)]
[] m: integer; S(i – 1)? insert(m) 
[m < n  S(i + 1)!insert(n); n := m
[] m = n  skip
[] m > n  S(i + 1)!insert(m)]]]
User process S(0) interacts with the processes as follows:
S(1)!has(n); …; [(i:1..100)S(i)?b  …]
27
Exercise
• Extend the previous solution to respond to a command to yield the
least element of the set and to remove it from the set. The user
program will invoke the facility by a pair of commands:
S(1)!least();
[x: integer; S(1)?x  … use x … [] S(1)?noneleft()  …]
or, the user wishes to scan and empty the set, he may write:
S(1)!least();
more: boolean; more := true;
*[more; x: integer; S(1)? X  … use x …; S(1)!least()
[] more; S(1)?noneleft()  more := false]
28
Download