Professional Documents
Culture Documents
Concurrency: Execute two or more pieces of code at the same time Why? No choice: - Geographically distributed data - Interoperability of different machines - A piece of code mustserve many other client processes - To achieve reliability By Choice: to achieve speedup sometimes makes programming easier (e.g. UNIX pipes)
Definitions
Concurrent process execution can be: - interleaved,or - physically simultaneous Interleaved: Multiprogramming on uniprocessor Physically simultaneous: Uni-or multiprogramming on multiprocessor Process, thread, or task: Schedulable unit of computation Granularity: Process size or computation to communication ratio - Too small: excessive overhead - Too large: less concurrency
Precedence Graph
Consider writing a program as a set of tasks. Precedence graph: Specifies execution ordering among tasks S0: S1: S2: S3: S4: A:= X Y B:= X + Y C := Z + 1 C := A - B W:= C + 1 S0 S1 S3 S2
S4 Parallel zing compilers for computers with vector processors build dependency graphs
S2
S3
Quit;
Join is an atomic operation
Example: bank teller /* Joe has $1000, split equally between savings and checking accounts*/ 1. Subtract $100 from Joes savings account 2. Add $100 to Joes checking account
Other processes should never read Joes balances and find he has 900 in both accounts.
Concurrency Conditions
Let Si denote a statement Read set of Si: R(Si) = {a1,a2,,an) Set of all variables referenced in Si Write set of Si: W(Si) = { b1, b2, , bm}, Set of all variables changed by si C := A - B R(C := A - B) = {A , B} W(C := A - B) = {C} Scanf(%d , &A) R(scanf(%d , &A))={} W(scanf(%d , &A))={A}
Bernsteins Conditions
The following conditions must hold for two statements S1 and S2 to execute concurrently with valid results: 1) R(S1) INTERSECT W(S2)={} 2) W(S1) INTERSECT R(S2)={} 3) W(S1) INTERSECT W(S2)={}
S3
S4
S2
S4 S6
S3
S5
S1; Count := 3; FORK L1; S2; S4; FORK L2; S5; Goto L3; L2: S6; Goto L3 L1: S3; L3: JOIN Count S7;
Comparison
Unfortunately, the structured concurrent statement is not powerful enough to model all precedence graphs.
S1 S1 S1
S1 S1 S1 S1
Comparison(contd)
Fork and Join code for the modified precedence graph:
S1; Count 1:=2; FORK L1; S2; S4; Count2:=2; FORK L2; S5 Goto L3; L1: S3; L2: JOIN Count1; S6; L3: JOIN Count2; S7;
Comparison(contd)
There is no corresponding structured construct code for the same graph However, other synchronization techniques can supplement Also, not all graphs need implementing for real-world problems
Overview
System Calls - fork( ) - wait( ) - pipe( )
- write( )
- read( ) Examples
Process Creation
Fork( ) NAME fork() create a new process SYNOPSIS # include <sys/types.h> # include <unistd.h> pid_t fork(void) RETURN VALUE success parent- child pid child- 0 failure -1
Int pipe(pfd)
int pfd[2]; PARAMETER Pfd is an array of 2 integers, which that will be used to save the two file descriptors used to access the pipe RETURN VALUE: 0 success; -1 error.
Pipe() - structure
/* first, define an array to store the two file descriptors*/ Int pipe[2];
/* now, create the pipe*/ int rc = pipe (pipes); if(rc = = -1) { /* pipe() failed*/ Perror(pipe); exit(1); } If the call to pipe() succeeded, a pipe will be created, pipes[0] will contain the number of its read file descriptor, and pipes[1] will contain the number of its write file descriptor.