ch7.pdf

*+ & ' &( )
,- ./ + %/
0" /
%/ .
)
*+ 12
(Monitors)
3+ !
2000 78 8 8 2 4 05" 0! %/
0
"#
$
!
% !
" # –
"-/
! ! &+ 8 /
!
.!"
!!
> & ,
<
&+ 7
! ! "-/ : /=
+
.
: /= 0 0 /
7! @ ? +
C
–
(" &( )
+A
&B ' 7 !
G ' 3 / 0"=' 7 > H
0 4
0! &D E
. !
0 n I"2 &+
% &B ' 0! ! ! n – 1
&+ , : /
+ counter
J
"
&B ' & K n < / 7 !
+
&B ' &+ ! ! !808 + J : . %+ B 0! L & (8 0 M
. +
N
! ! O8 K + 8 N
(
!
)
" # –
!
:
:A
&B '
#define BUFFER_SIZE 10
typedef struct {
...
} item;
item buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
int counter = 0;
(
)
" # –
(" 7 ! @
!
:
item nextProduced;
item nextConsumed;
while (1) {
while (counter == BUFFER_SIZE)
; /* do nothing */
buffer[in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
while (1) {
while (counter == 0)
; /* do nothing */
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
}
C
7! @
1
(
" # –
)
S@ & T Q0"L &+
3
38 + 8
:
!
+ counter– 8 counter++
Q0"L &+
+ > Q /R U
S@ & T
.! S@ Q0"L & V8 ! K0
+ Q0"L : &+ , : / Q 0 R : :
counter++
register1 = counter
register1 = register1 – 1
counter = register1
Q0 R
. " >
3 +7 I! U
counter- register2 = counter
register2 = register2 – 1
counter = register2
(
" # –
)
!
Q0"L &+
X
C
8
(" 7 ! @ 8!
W
3 +7 Q 0" ! , : / H
780 &+ 0 % &B ' 8 /
. " > (interleave) W + 3 Q0"L &+ :
N Q 0" ! 7 .
8 counter = 5
Y IG
+
.(counter = 5 : " [ &T ) " > 0 + . N 8
producer:
producer:
consumer:
consumer:
producer:
consumer:
register1 = counter
register1 = register1 + 1
register2 = counter
register2 = register2 – 1
counter = register1
counter = register2
(register1 = 5)
(register1 = 6)
(register2 = 5)
(register2 = 4)
(counter = 6)
(counter = 4)
& ! ' (
Q0"L &+ 7 ! @ : ] 3E 0! & ,
[
J 0 E 8 0! + ! A
&B '
+
3 @ &/ 7 4@ &
8 /
7! @
+
7 ! @ Q /R &+ ! !
! ! "-/
&M+ ) ^
* +
7! @ ! U & E
.
,+ V0
! ! &+ + !
&M+ ) ^
! ! &+ 8 /
. !
78 + 7
)*
& (8
* + )* !
0 ,- ./ + %/
0" /
%/ .
)
*+ 12
(Monitors)
3+ !
2000 78 8 8 2 4 05" 0! %/
0 M
.!0 ! % )+
W" > +
. " < %/
!
N@ [
0!
*+ & ' &( )
! ! &+ + ! +
"-+
& !0 !
*+ & ' . 7 ! @
.!0 ! 0 V 3E 0!
0! 7 ! @ . V8 & , &( ) : : /=
*+ & ' &( )
*+ & ' !0 8 " / % ! 7 ! @ !0 ! 0 V
*+ & '
.!" !"K
,U / _ &
+
*+ & ' &( )
+ ' 0
.!7 !08E + 0 !8 * 0 B 8 , @ H& >8!
* +
)*
! ,)
' (
& >8! ,U / .
7 ! @ ` H, !"K
*+ & '
.!" !"K
> I ' 0!
7 ! @ V8
*+ & ' !0 8
%!
,
@ .
8 ,) !"K
*+ & '
> I ' 0!
7! @ ` W
- %E H )
*+ & ' &+ !808 B
7! @ ! U
!8 * Q0"L &+ " /
*+ & ' &+ !808 + U+ 7 ! @
.!" & K 1 "U &+
2
(
)
* +
)*
! ,)
' (
*
.!
!8 * 0 B
,)
' P2 8 P1 7 ! @ 8!
+H
I 0 0
*+ & ' &+ !808 = M
7 ! @ V8
7 V
*+ & ' &+ 7 ! @
!808 Q U ! + 5 + ' .
. + & ! !">8
, "K0! 7 ! @ &+ !808 7"T [R
> L 7 W0 + R + 7 ! @ &/ ! Y 3 "
.! S@ 3 @ E
*+ & '
>
3 7 0! S( H "
7 ! @ > ,R 3 , ) 0 +0! a & "W ` 3 " /
., !
!
A
J 7
+ ^M 0 3E
%/
+
:
7! @
entry section
critical section
exit section
reminder section
} while (1);
2 A
.!" !"K
"
J
A
!0 M Hturn b *L ! R
Pi 7 ! @
turn == i
.!" !"K
., 0! :& (8
*+ & ' !0 8 "
!0 M Hflag
Pi 7 ! @
J
8! ("+ & 0E
flag [i] == true
:Pi 7 ! @
:Pi 7 ! @
do {
do {
flag[i] := true;
while (flag[j]) ;
critical section
flag [i] = false;
remainder section
while (turn != i) ;
critical section
turn = j;
reminder section
} while (1);
. K 0,
' +
.
7! @ :
.
0 K
do {
1 . L :& (8
*+ & ' !0 8 "
+ &( )
@
H
3 .2 8 1
0"%( 7
:Pi 7 ! @
flag [i]:= true;
turn = j;
while (flag [j] and turn = j) ;
critical section
flag [i] = false;
remainder section
} while (1);
: + +H
7 ! @ 8!
0 V + 0_
*+ & ' &( )
. K 0,
(
do {
0 . 3 " R &+ "
.!" !
} while (1);
0 V + 0 & >8! ,U / _
&
+ '
** .
@
) *
H
0 V + 0 & >8! ,U / _
n
,)
, 0! ! R .
*+ & ' &+ !808 7 N @ 7 ! @
*+ & ' !0 8 + & ! 0 ! R : ]" &
7! @
.!"
Pi % E i < j W H
, 0! 0 ! R . Pj 8 Pi 7 ! @ 8! W
.!"
!"K
*+ & ' !0 8 Pj & W8
("
d
+ 0 ! R & / ! R (" <
Q0"L : &+ "
7 T ? . & "/
+.
: +
1, 2, 3, 3, 4, 4, 4, 5, …
3
(
& ,
.!"
n
*
)
& J( ? . % +
I /R ( 7 ! @ &
H
+&
/)V &+ k
** -
]" ! / 0"%( : 0!
0! ! R) ? O87 80
.a = c && b < d
i = 0, …, n – 1
,)
,
8 a < c (a, b) < (c, d)
! R max (a0,…, an-1)
.k ai
+& !
:A
J
boolean choosing[n];
int number[n];
. "
& (8
!0 M
L 8 , 0!
!M +?
&+ &
do {
choosing[i] = true;
number[i] = max(number[0], number[1], …, number [n – 1])+1;
choosing[i] = false;
for (j = 0; j < n; j++) {
while (choosing[j]) ;
while ((number[j] != 0) && (number[j,j] <
number[i,i])) ;
}
critical section
number[i] = 0;
remainder section
} while (1);
56 123 4
& (8
*+ & ' &( )
56 123 4
0" /
%/ .
)
*+ 12
(Monitors)
3+ !
2000 78 8 8 2 4 05" 0! %/
(
)
0 ,.! < %/ 0
:TestAndSet
:TestAndSet
boolean TestAndSet(boolean &target) {
boolean rv = target;
tqrget = true;
return rv; }
(
-3
7* 8
:Pi
)
56 123 4
:Swap
-3
7* 8
:(, 0! & (8 0 M +) A
19*
!!
7! @
0" ! 7 !
+ 3"
> S@ & T Q0"L &+
+ S@ & T Q0"L &+ 0 &B ' 7 &/ . 0 M :TestAndSet
.
!0 M , 0! &+ 0 3E 4# 8 ! &) M , 0!
.
Y"R
+ S@ & T Q0"L &+ 0 J 8! 0 M :Swap
56 123 4
., 0! & (8 0 M + lock ("+ J :A
@ ./ + &
7! @ "
boolean lock;
boolean waiting[n];
do {
while (TestAndSet(lock)) ;
critical section
lock = false;
remainder section
19*
!!
:Pi 7 ! @
do {
key = true;
while (key == true)
Swap(lock,key);
critical section
lock = false;
remainder section
}
}
4
6 3
& (8
*+ & ' &( )
0 ,- ./ + %/
6 3
%/ .
)
*+ 12
(Monitors)
3+ !
2000 78 8 8 2 4 05" 0! %/
6 34
* +
:(. & (8
)*
wait (S):
while S 0 do no-op;
S--;
signal (S):
S++;
! ,)
!0 M +) A
6 3
!!
semaphore mutex;
:Pi 7 ! @
do
{
+ ^M & (8 !0 M 7 4@ & , b *L J . 0" /
.,
+ ! + V signal 8 wait 0" ! 8! 7 !
wait(mutex);
critical section
signal(mutex);
remainder section
:!"
7 Q0"L &+ wakeup 8 block ! Q /R 8!
: +
.!08E 0! 1 U ,( ' &+ 0
"K 7 ! @
.! W
7 0P
1 U 7! @ >
6 3
$ U Q0"L : &+ 0 0" /
wait(S):
7 Q0"L &+ 0" / .
typedef struct {
int value;
struct process *L;
} semaphore;
}
while (1);
:
$ U
3
3
%/
0! B Q /R 7
add this process to S.L;
block;
}
signal(S):
S.value++;
if (S.value <= 0) {
remove a process P from S.L;
wakeup(P);
block
wakeup (P)
6 34
80 Q /R 5 '
S.value--;
if (S.value < 0) {
>
Y
$ U
.
+
"/R 0 + 3 " R &+ 0" / 7 3 "
.! !
7! @
V / ' Pi 7 ! @ 0! A Q /R
!
"K
Y
.!" > Pj 7 ! @
L & (8 0 M + 0" / . 7 0 :
+
Pi
Pj
M
M
A
wait(flag)
signal(flag)
B
}
5
+; 1!
Q0"L &+ 7 ! @ ] 8! & !"
3/ 7
^ " +&
)
& W [
&+ 1!
! K0 e"V8 B 3 @ +
. +f
7! @
+ L & (8 0 M + 0" / 8! Q 8 S
:
P0
wait(S);
wait(Q);
M
signal(S);
signal(Q)
Y & "/
. 0 M 8! 8
., .
,( ' 0!
& , b *L ! R .
0 / 0" /
. ! g K !"K &+
L 3E 0 M & , b *L ! R . 0 M 8! 0" /
+ 0
0 / 0" / . 3 "
.!
7 ! @
: !! 0 K
binary-semaphore S1, S2;
S1 = 1;
S2 = 0;
! @ 0!
.!"
6 3
"
0 M 8! 0" / 7 !
int C;
:& (8
C = initial value of S;
+ LIFO <
7 0" / .
Y
!
I % B
7 ! @ $L
. + N @ [*V , : /
7! @ ,( ' : 0! .
7
0 / :!0 ! !">8 0" / e" 8!
!M
7
+; 1!
)
+
P1
wait(Q);
wait(S);
M
signal(Q);
signal(S);
&
0 !8 *
(
!0 M
7 ! @ $L 7 !
,( ' 0! : + +
T [*V 8 ,)+ :+ &+ "
0" /
(
&
)
6 3
wait operation
wait(S1);
C--;
if (C < 0) {
signal(S1);
wait(S2);
}
signal(S1);
signal operation
wait(S1);
C ++;
if (C <= 0)
signal(S2);
else
signal(S1);
4 3< , !
& (8
*+ & ' &( )
0 ,- ./ + %/
0" /
4 3< , !
*+ 12
(Monitors)
3+ !
2000 78 8 8 2 4 05" 0! %/
: 7! @
%/ .
!8 *
%
&( ) &
&B ' +
0 + &+ N-+ : 0!
–
)" 8
C")
C
(" &( )
"K &( )
0"K Sd &( )
6
" # –
:(& (8
!
!0 M +) A
(
:
(" 7 ! @
…
produce an item in nextp
…
wait(empty);
wait(mutex);
…
add nextp to buffer
…
signal(mutex);
signal(full);
} while (1);
! *
* =
:(& (8
!0 M +) A
!
(" 7 ! @
: ) " 7! @
wait(wrt);
…
writing is performed
…
signal(wrt);
!0 M +) A
! *
)
!!
int readcount = 0;
= ?@
wait(full)
wait(mutex);
…
remove an item from buffer to nextc
…
signal(mutex);
signal(empty);
…
consume the item in nextc
…
} while (1);
(
semaphore mutex = 1, wrt = 1;
:(& (8
:
do {
do {
semaphore chopstick [5] = {1};
!
!!
semaphore full = 0, empty = n, mutex = 1;
" !> 6
" # –
)
* =
:
!
"K 7 ! @
wait (mutex);
readcount ++;
if (readcount == 1)
wait (wrt);
signal (mutex);
…
reading is performed
…
wait (mutex);
readcount --;
if (readcount == 0)
signal (wrt);
signal (mutex);
!
(
)
" !> 6
= ?@
:< i C")
!!
!
7! @
do {
wait (chopstick[i])
wait (chopstick[(i+1) % 5])
…
eat
…
signal (chopstick[i]);
signal (chopstick[(i+1) % 5]);
…
think
…
} while (1);
7
* + &
& (8
*+ & ' &( )
0 ,- ./ + %/
0" /
%/ .
)
* + AB
(Monitors)
3+ !
2000 78 8 8 2 4 05" 0! %/
(
:!"
3 R
)
7 Q0"L &+ T e" 7
8 wait > ?
,)+ :+ 8
, 0!
! ! &+ 3 /
5 + b[ ) " & +
.,
7 ! @ %/
v
A
(
J .
H
> 0
B
),
S@ 3
7 Q0 R 0!
v
J &+
!
:(,
("+ J
region v when B do S
v
J &+
"
> 7 H
/
% ! 7 ! @ H!"
e >0 A
.
(
" # –
: !
0 VA
> Q0 R : V8
.
+ !
J . &+ &
*+ 12
,U / %
3 /
!)
:!0 !
+A
&B ' 7 0 & "/
@ ' 0
*+ &M[
* + &
*+ &M[ Q0 R "K
7 ! @ . V8
...
+ 70 0 B ("+ Q0 R 0 M
.!"
> Q0 R H + , 0! B W
% ! 7! @ &
7
B 7 ! @ H + , 0! B W
.!" , 0! + + B 0 M 8
v &+ _"+
*+ &M[
C
H
(" &( ) :& "/ .
:A
struct buffer {
int pool [n];
int count, in, out;
(" 7 ! @
region buffer when( count < n) {
pool[in] = nextp;
in:= (in+1) % n;
count ++;
}
region buffer when (count > 0) {
nextc = pool[out];
out = (out+1) % n;
count --;
}
)
: +g
!!
}
region x when B do S
* + &
&B ' 0! 0 nextp
0!
> : wait - signal
! : signal - wait
,)+ :+ : wait - wait
0 K 7 !
: !
+ 5 + b[ 0 K .
* + &
v: shared T
.
, R0 < R 8 0" / 7 , 0! !
! ! &+ 3 /
! signal
K 0 7
3
J
x
J &+
semaphore mutex, first-delay, second-delay;
int first-count, second-count;
! mutex J
.
&M[ !0 8 " B Q0 R 3!"+ , 0! 2 K &+ 7 ! @ . W
4# 8
B first-delay 0" / 80 + H!"
*+
$L &+ H
+ 70 0 B J 0 M 0 +8! " + & E 7 N @
.!"
M second-delay 0" / 0 B
: /= 0
C
7! @
*+ &M[ &+ 0 *
8
) region x when B do S
(
wait (mutex);
while (!B) {
first_count ++;
if (second_count > 0)
signal (second_delay);
else
signal (mutex);
wait (first_delay);
first_count --;
second_count ++;
if (first_count > 0)
signal (first_delay);
else
signal (second_delay);
wait (second_delay);
second_count --;
}
3
S;
if (first_count > 0)
signal (first_delay);
else if (second_count > 0)
signal (second_delay);
else
signal (mutex);
& (8
*+ & ' &( )
0 ,- ./ + %/
0" /
%/ .
)
*+ 12
(Monitors)
C
2000 78 8 8 2 4 05" 0! %/
C
I
5 + b[
0 K
(Monitor)
7 %!
.,
7! @
monitor monitor-name
{
shared variable declarations
procedure body P1 (…)
{
...
}
procedure body P2 (…)
{
...
}
procedure body Pn (…)
{
...
}
{
initialization code
}
}
C
(
4
3+
!
.
+ H /+ B 3 +
%/
C
)
! . 0! " + 7 ! @ . &
:!" 3 R 7 Q0"L &+ _
+
J
condition x, y;
.!"
&
W .
>
signal
!
8 wait I /R +
"
_
J
$V"
"K 7 ! @ U x.wait () /R
.
> 0 x.signal () /R % ! 7 ! @
+ 7+ 0
$V" 7 ! @ . M V! x.signal () /R
.!0
h ` /R : H +
$V"
7! @
7 ,
D ( E-
C
9
" !> 6
= ?@
!
:3 +
(
void pickup (int i) {
state [i] = hungry;
test [i];
if (state [i] != eating)
self [i].wait();
}
(
!0 M +)
J
:
semaphore mutex = 1;
semaphore next = 0;
int next-count = 0;
:!"
: % > 7
&U[V + F
I 80
.!"
: /= 3 +
(
"
)
.!"
$V"
"K
& *
7! @ <
0 , "(8 0 / :
! 0! 0 *
C
8 2
7! @ :
g
K
)
C
3
0 / . 8 0" / .
x
_
J
+
"
R )
8
/ V I8 :: !
: % ! X80
Q0"L &+ 2
7
&+
! @ 7 Q0"L &+ x.signal 8 x.wait I /R
x.wait ()
x.signal ()
x_count ++;
if (next_count > 0)
signal (next);
else
signal (mutex);
wait (x_sem);
x_count --;
if (x_count > 0) {
next_count ++;
signal (x_sem);
wait (next);
next_count --;
}
(
0B 0 K 7 !
x.wait (c)
wait
!
3
+ 7 + 7! @ .
!
(FCFS)
.!"
!
: "
signal(mutex);
, "(8 <"
void putdown (int i) {
state [i] = thinking;
// test left and right neighbors
test ((i+4) % 5);
test ((i+1) % 5);
}
semaphore x_sem = 0;
int x_count = 0;
wait(mutex);
…
body of F;
…
if (next-count > 0)
signal(next)
else
0"%( 7
!
void test(int i) {
if ( (state[(I + 4) % 5] != eating) && (state[i] == hungry) &&
(state[(i + 1) % 5] != eating)) {
state[i] = eating;
self[i].signal();
}
}
3
:(& (8
= ?@
!0 S%+ 80 I % ] H0 ! + 80 I % ]
!$ U
monitor dp
{
enum {thinking, hungry, eating} state[5];
condition self[5];
void pickup(int i)
// following slides
void putdown(int i)
// following slides
void test(int i)
// following slides
void init() {
for (int i = 0; i < 5; i++)
state[i] = thinking;
}
}
C
" !> 6
)
0B 0 K
"K + & , b *L Q0 R . c
/ &+ 7 ! @ , "(8 0 / 3 " R &+ c 0 M
.!"
Kj
]" &
7 ! @ !"
> x.signal V8
.!"
+ 7+H +& !
monitor ResourceAllocation {
boolean busy;
condition x;
void acquire (int time) {
if (busy)
x.wait (time);
busy = true; }
void release () {
busy = false;
x.signal (); }
void init () {
busy = false; }
}
)
C
3
// A Correct Use:
R.acquire (t);
…
access the resource
…
R.release ();
10
F13
( " B ,GH
I
-! 3
08E!
,)+ :+ 8 3 /
5 + b[ ) " & +
!!!,
.
@
.
!
0" / 7 , 0! !
0 K 7 !
: !
@ ' 0
C 2 +
Q0"L &+
7+&
:!" 7E 0 7 _
?
0! k
+ 03+
) !
18
/R ,*L ^
)
l '
<
I
8!
! 0! !"K
1+J ' (
+ ) ,*L 7 3 /2
"+3+
"K
+
+0
7! @
. ! < T b *L
! !808 W0! 7 0" R 38 +
7! @ `
. ! g K !"K &+ 0 3 + ! 0 K
! k &+ & (8 7 > ?) 38 + , : / 7 ! @ .
! 7E %D 0 & g K k , : / 7 ! @ .
... , : / 7 ! @ .
(
G>
+ 0 "/
: ' 0
: + ' 0
2K L 3
2000
& (8
*+ & ' &( )
0 ,- ./ + %/
0" /
%/ .
)
*+ 12
(Monitors)
3+ !
2K L 3
H % l8 ]
@
V7
- e " 2 4 05" 0!
! @ W7 ! @ ] 8 % 0 ]
mutex 7
"
0 3! +5 + , > 2 4 05"
.
!
! ! 7 ,B *
+ M8
7 +
&U[V 0!
! ! 7 ,B *
+
.!"
!
) " H "K
V 8_
J
. 7
$V"
7 ! @ 3! ?
+ 2 4 05" 0!
.!"
!
turnstile < &+ , "(8 + $L 0 K
.
+
7
&U[V 0!
2000
k+
7 ,B *
+ 7! @ .
) 0! 2000 78 8
.
!
(interrupt mask) & V8
M 7
!
spinlock
V 7 7! @ ]
) 0!
&U[V 7 ,B *
+&) ^ "
V : .!"
. "
!
"
8 mutex 3 " R &+ dispatcher object 7 3 "
: D/
.! !
0" /
, /'
! K0 7 3 "
dispatcher object 7 !
+
.!0 ! _
J &+ 0 )+ ,
! K0 . .!
.
.
!<T
: / n @8 . I 0 !
/ 7
/
!n @
3 @ Q5 " : &+
14 H10 H9 H8 H7 H6 H3 H2
: )" & +
: / 0 +0!
4 " ( :3 +
R )
C++ : 7 & + 3 +7
N 0! 0 : / :
"
*
0! G ' 0 *
: /
n @
0 ! &+ - 3 0! G ' 0 ) " & +
K <
/ 3! ! , ! 7 =
/ 3! ! , ! 7 =
n @ I 0 0! 780 & 7 / K
n @ I 0 0! 780 & 7 N + K
11