1111 communicating sequential processes based on: c. a. r. hoare, communicating sequential...
TRANSCRIPT
1111
Communicating Sequential Processes
Based on:C. A. R. Hoare, Communicating Sequential Processes, CACM,
21(8):666-677, November, 1978.
1
2222
Outline
• Background and motivation• Concepts and notation• Examples
2
3333
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
4444
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
5555
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
6
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 ] ]]
7777
Outline
Background and motivation• Concepts and notation
– Basic and structured statements
• Examples
7
8
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>
9
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>
10
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>
11
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?
12
Assignment
• Simple vs. structured value– 0, true, 10 + y, x + y, …– (10, 20), (x, y), point(10, 20), done()
• 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>}
c(e1, e2, …, en)
13
Matching Assignment
• 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
x := ec(x1, x2, …, xn) := c(e1, e2, …, en)
14
Example
1. x := x + 12. (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?
15
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>}
16
Example
1. cardreader?cardimage
2. lineprinter!lineimage
3. X?(x, y)
4. DIV!(3*a + b, 13) Q: if 3 and 4 correspond?
5. console(i)?c
6. console(j - 1)!“A”
7. X(i)?V()
8. sem!P()
17
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>
18
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.
19
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>
20
Exercise
• Write a process that finds a maximum value of an array.
• Write a process that performs a binary search on a sorted array.
21
Example: CoroutinesRead 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]
22
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)]
[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]
• Compute a factorial by the recursive method, to a given limit.
23
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?
24
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()
25
Exercise• Extend the set ADT to introduce two new operations
– S!remove(x)
– S!least(); …; x: integer; [S?x … use x … [] S?noneleft() …]
26
Exercise• Define a bounded stack ADT by providing typical stack operations
such as push, pop, top, and isEmpty.
27
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 …]
28
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]