- •28.11.12 Лекция 11
- •8.Язык, технология
- •Класс реактивных систем
- •Сообщения
- •Erlang, Bjarne Däcker,
- •Параллельная композиция
- •Трасса – это последовательность действий на некотором пути в графе действий.
- •Спецификация параллельной композиции
- •Коммуникационные протоколы
- •ввод
- •Протокол n-ABP модификация протокола чередования битов
- •Протокол скользящего окна
- •Протокол рукопожатия
- •Протокол рукопожатия
- •Алгоритм Петерсона взаимного исключения доступа
- •process main(); { Peterson(0, 1) || Peterson(1, 0) }
Протокол n-ABP модификация протокола чередования битов
process nABP( ) { |
|
(Alternating Bit Protocol) |
|
||
Отправитель() || Получатель() } |
|
||||
int timeout; |
// время ожидания в миллисекундах |
|
|||
process Отправитель() { |
|
|
|
||
int прочитано = 0; //номер текущего блока |
|
||||
read: |
|
ввод?(Data |
блок); |
|
|
прочитано’ = прочитано + 1; |
|
|
|||
send: |
Получатель ! Данные(блок, контрольнаяСумма(блок)), прочитано); |
||||
receive { ОК(int номер): |
if (номер прочитано) |
#send |
|||
else |
#read |
|
|
|
|
|
after timeout: |
#send |
|
|
|
} |
} |
|
|
|
|
|
|
|
|
|
|
process Получатель() { |
|
|
|
||
int записано = 0; |
|
|
|
||
loop: receive Данные(Data блок, int сумма, int номер); |
|
||||
if ( посчитатьСумму(блок) сумма ) |
#loop |
|
|||
|
else { Отправитель ! OK(номер); |
|
|
||
|
if ( номер записано+1 ) #loop |
|
|
||
|
else |
#write |
|
|
|
} |
|
|
|
|
|
write: |
вывод(блок); |
|
|
|
|
|
записано’ := записано + 1; |
|
|
||
|
#loop |
|
|
|
|
} |
|
|
|
|
|
Протокол скользящего окна
Блоки посылаются друг за другом без ожидания подтверждения с записью в окно. Если требуется повторить передачу, этот блок берется из окна. Число блоков, посылаемых в текущий момент, регулируется размером окна. Заводится таймер на каждый блок
окно - круговой буфер блоков
Протокол рукопожатия
s
u
a
S
b
M1
M2
c
R r
d
Передатчик S |
Приемник R |
|
Ненадежные каналы |
потеря сообщений |
|
Медиумы M1, M2 |
|
|
process GS { |
|
Протокол |
S || M1 || R || M2 |
|
|
}
spec GS = s? r! u!
Протокол рукопожатия
message a, b bool sa, sb
Указатели текущего исполняемого действия: pcS=s, pcR=r list ({a}) qa = nil;
list ({b}) qb = nil; process S(: #exit) {
s: if (b) #exit
if (sa) send a; #s
}
process R() { r: receive(a);
if (sb) send b; #r
}
process HandShake(:#exit) { S(:#exit) || R(:) } состояние: ( qa, qb, sa, sb)
начальное состояние qa=nil; qb=nil
process S(: #exit) { |
|
process R() { |
|
||
s: if (b) #exit |
|
r: receive(a); |
if (sa) send a; #s |
|
if (sb) send b; #r |
} |
} |
process SR() { //qa = [a+] эквивалентно qa != nil a0: inv (qa, qb) = (nil, nil);
s(sa: #a1: sa #a0) a1: inv ([a+], nil);
s #a1 | r (sb & qa’=nil #a2: sb & qa’!=nil #a3 :sb & qa’=nil #a0: sb & qa’!=nil #a1)
a2: inv (nil, [b+]);
s #exit | r (qa’=nil #a2: qa’!=nil #a3) a3: inv ([a+], [b+]);
s #exit | r (qa’=nil #a2: qa’!=nil #a3) a2 и a3
[nil, |
[a+, |
[a*, |
nil] |
nil] |
b+] |
exit
Алгоритм Петерсона взаимного исключения доступа
type PC = enum(0, 1, 2, 3, cs, 4); type PROC = enum(0, 1);
PROC turn = 0;
type FLAGS = array(PROC, bool); FLAGS flag = for(PROC i){false}; type PCS = array(PROC, PC);
PCS pc = for(PROC i){0}; process Peterson(PROC a, b) {
0:flag[a] = true;
1:turn = b;
2:if (flag[b]) #3 else #cs;
3:if (turn = b) #2 else #cs; cs: skip;
4:flag[a] = false;
}
process main(); { Peterson(0, 1) || Peterson(1, 0) }
Состояние: (flag[a], flag[b], turn, PC[a], PC[b])
Переменные состояния: (fa, fb, turn, pa, pb) process PetPet(); {
a0: invariant (fa, fb, turn, pa, pb) = (f, f, *, 0, 0);
0a | 0b #b1 |
|
|
|
|
|
a1: inv |
(t, f, *, 1, 0) |
; |
b1: inv |
(f, t, *, 0, 1) |
; |
1a | 0b #c0 |
|
0a #c0 | 1b |
|
||
a2: inv |
(t, f, b, 2, 0) |
; |
b2: inv |
(f, t, a, 0, 2) |
; |
2a | 0b #c1 |
|
0a #d1 | 2b |
|
||
a3: inv |
(t, f, b, cs, 0) |
; |
b3: inv |
(f, t, a, 0, cs) |
; |
csa | 0b #f5 |
|
0a #e5 | csb |
|
|
|
a4: inv |
(t, f, b, 4, 0) |
; |
b4: inv |
(f, t, a, 0, 4) |
; |
4a#a0 | 0b #f4 |
|
0a #e4 | 4b #a0 |
|
||
a5: inv |
(f, t, a, 0, 3) |
; |
b5: inv |
(t, f, b, 3, 0) |
;~a5 |
0a #d2 | 3b #b2 |
|
3a #a2| 0b #c2 |
|
process Peterson(PROC a, b) { 0a: flag[a] = true;
1a: turn = b;
2a: if (flag[b]) #3 else #csa;
3a: |
if (turn = b) #2 else #csa; |
csa: |
skip; |
4a: |
flag[a] = false; #1a |
}
c0: inv (turn, pa, pb) = (*, 1, 1);
1a | 1b #d1
c1: inv (b, 2, 1) ;
2a | 1b #f2
c2: inv (b, 3, 1) ; 3a #c1 | 1b #d6
c3: inv (a, cs, 2) ;
csa | 2b #d8
c4: inv (a, 4, 2) ;
4a #b2| 2b
c5: inv (a, 4, 3) ; 4a #a5 | 3b #c4
process Peterson(PROC b, a) { 0b: flag[b] = true;
1b: turn = a;
2b: |
if (flag[a]) #3 else #csb; |
3b: |
if (turn = a) #2 else #csb; |
csb: |
skip; |
4b: |
flag[b] = false; #1b |
d1: inv (a, 1, 2) ;
1a #e2 | 2b #d2 d2: inv (a, 1, 3) ;
1a #c6 | 3b #d1
d3: inv (b, 2, cs) ;
2a #c8 | csb d4: inv (b, 2, 4) ;
2a | 4b #a2 d5: inv (b, 3, 4) ;
3a #d4 | 4b #b5
process Peterson(PROC a, b) { 0a: flag[a] = true;
1a: turn = b;
2a: if (flag[b]) #3 else #csa;
3a: |
if (turn = b) #2 else #csa; |
|
csa: |
skip; |
|
4a: |
flag[a] = false; |
#1a |
}
c6: inv (b, 2, 3) ;
2a | 3b #d3
c7: inv (b, 3, 3) ;
3a #c6 | 3b
c8: inv (b, 3, cs) ; 3a #d3 | csb #d5
e2: inv (b, 2, 2) ;
2a | 2b #c6
e3: inv (b, 3, 2) ; 3a #e2 | 2b #c7
e4: inv (a, 1, 4) ;
1a #d4 | 4b #a1 e5: inv (a, 1, cs) ;
1a #d3 | csb #e4
process Peterson(PROC b, a) { 0b: flag[b] = true;
1b: turn = a;
2b: if (flag[a]) #3 else #csb;
3b: |
if (turn = a) #2 else #csb; |
|
csb: |
skip; |
|
4b: |
flag[b] = false; |
#1b |
d6: inv (a, 3, 2) ; ~c6
3a #c3 | 2b
d7: inv (a, 3, 3) ; ~c7
3a #d8 | 3b #d6
d8: inv (a, cs, 3) ; ~c8 csa #c5 | 3b #c3
f2: inv (a, 2, 2) ; ~ e2
2a #d6 | 2b
f3: inv (a, 2, 3) ; ~ e3 2a #d7 | 3b #f2
f4: inv (b, 4, 1) ; ~e4
4a#b1 | 1b #c4
f5: inv (b, cs, 1) ; ~e5 csa #f4 | 1b #c3