Title: Concurrencysynchronization using UML state models
1Concurrency/synchronization using UML state models
- November 27th, 2007
- Michigan State University
2Overview
- Programming model used to implement
multi-threaded concurrency - Threads
- Monitors
- Condition synchronization
- Application of UML 2.0 state diagrams to model
and reason about concurrent interactions
3Overview
- Programming model used to implement
multi-threaded concurrency - Threads
- Monitors
- Condition synchronization
- Application of UML 2.0 state diagrams to model
and reason about concurrent interactions
4Thread Concepts
- A thread is always in one of three states
context switch
running
ready
context switch
signal
wait
suspended
5Sequence diagram
sd scenario n
Passive object
Active object
b sharedBuffer
c Consumer
startWrite()
thread is ready
thread is running
startRead()
Thread is suspended
Thread is not running in this object
Snapshot of execution in progress
6Thread Concepts Context Switch
- A context switch is the simultaneous
transitioning of - one thread from the ready state to the running
state - AND
- the previously running thread from the running
state to another state (ready or suspended).
7sd scenario n
b sharedBuffer
c Consumer
startWrite()
startRead()
Producer switches out, consumer switches in
Consumer suspends, producer switches in
8Monitors
- Class-like programming construct that allows at
most one thread to execute concurrently - Implemented by associating a lock with each
monitor object - Threads that execute the methods of a monitor
object must - obtain the monitor lock before doing anything
else in the method - release the lock just prior to returning.
9Monitor Synchronization
- When a thread attempts to acquire a monitor lock
that is held by another thread - the thread that made the failed attempt suspends
(i.e., changes state from running to suspended). - If the operating system causes a thread running
within a monitor to yield (context switch out),
the thread will not release the lock before
yielding.
10sd scenario6
State labels - producer enters and obtains lock
BoundedBuffer
LineConsumer
LineProducer
putLine(d)
locked
getLine()
Consumer fails to obtain the lock suspends
unlocked
Producer releases lock before returning
11Condition Synchronization
- Counting variables are used to encode the
synchronization state of a shared resource. - Conditions are predicates formed over one or more
counting variables. - Condition variables are associated with
conditions and used - by a waiting thread to register interest in a
change in the associated condition - CV.wait()
- by a running thread to inform registered waiting
threads of changes in the associated condition. - CV.signal()
- CV.broadcast()
12Producer-Consumer Example
- void BoundedLineBufferputLine(unsigned id,
const string line) - ACE_GuardltMonitorLockTypegt guard(lock_)
- while (isFull()) // condition buffer full?
- cout ltlt "WAIT-ON-FULL Producer " ltlt id ltlt
endl - fullCond.wait() // operation on condition
variable -
- buf.push_back(line)
- cout ltlt "PRODUCE Producer " ltlt id ltlt " "
- ltlt "(buf.size "ltlt buf_.size() ltlt ")" ltlt
endl - if (buf.size() 1) // counting variable
num elements in buffer - emptyCond_.broadcast()
-
13sd scenario2
BoundedBuffer
LineProducer
LineConsumer
okToRead
getLine()
locked size1
locked size0
unlocked Size0
getLine()
locked size0
wait()
unlocked size0
putLine()
locked size0
locked size1
broadcast()
unlocked Size1
Locked, then unlocked
14Producer Consumer Example
- void BoundedLineBuffergetLine(unsigned id,
string line) - ACE_GuardltMonitorLockTypegt guard(lock_)
- while (isEmpty()) // condition buffer state
- cout ltlt "WAIT-ON-EMPTY Consumer " ltlt id ltlt
endl - emptyCond_.wait()
-
- line buf_.front()
- buf_.pop_front()
- cout ltlt "CONSUME Consumer " ltlt id ltlt " "
- ltlt "(buf.size "ltlt buf_.size() ltlt ")" ltlt
endl - if (buf_.size() capacity_ - 1) //counting
variable num elements in buffer -
- fullCond_.broadcast() // operation on
condition variable -
15sd scenario2
BoundedBuffer
LineProducer
LineConsumer
okToRead
getLine()
locked size1
locked size0
unlocked Size0
getLine()
locked size0
wait()
unlocked size0
putLine()
locked size0
locked size1
Broadcast()
unlocked Size1
Locked, then unlocked
16Wait on a Condition Variable
- Waiting on a condition variable causes a thread
to - release its hold on the monitor lock
- change state from running to suspended
- When a call to wait returns, the calling thread
will be back in the monitor - will have reacquired the monitor lock
17sd scenario2
BoundedBuffer
LineProducer
LineConsumer
okToRead
getLine()
locked size1
locked size0
unlocked Size0
getLine()
locked size0
wait()
unlocked size0
putLine()
locked size0
locked size1
broadcast()
unlocked Size1
Locked, then unlocked
18Signal on a condition variable
- Signaling a condition variable
- changes to ready the state of some thread that is
suspended waiting on this variable - does not cause signaling thread to release the
monitor lock. - does not cause the signaling thread to change its
state - is a necessary but not sufficient condition to
cause another thread to return from a call to
wait on that variable
19sd scenario2
BoundedBuffer
LineProducer
LineConsumer
okToRead
getLine()
locked size1
locked size0
unlocked Size0
getLine()
locked size0
wait()
unlocked size0
putLine()
locked size0
locked size1
Broadcast()
unlocked Size1
Locked, then unlocked
20Condition Synchronization
- programmed using a loop
- guard checks the condition
- body executes a wait on condition variable.
- while (isEmpty()) // condition buffer
state - cout ltlt "WAIT-ON-EMPTY Consumer " ltlt id ltlt
endl - emptyCond.wait()
- // suspended (on wait) -gt ready (on signal) -gt
- // running (on context switch) -gt re-acquire
monitor lock -
- return from wait indicates that associated
condition was true at some point between
invocation of wait and return. - BUT -- some other thread could have made the
condition false before the waiting thread obtains
monitor lock - SO the thread must check that the associated
condition remains true - THUS it is important to place the wait inside a
loop.
21sd scenario2
BoundedBuffer
LineProducer
LineConsumer
okToRead
getLine()
locked size1
locked size0
unlocked Size0
getLine()
locked size0
wait()
unlocked size0
putLine()
locked size0
locked size1
Broadcast()
unlocked Size1
Locked, then unlocked
22Overview
- Programming model used to implement
multi-threaded concurrency - Threads
- Monitors
- Condition synchronization
- Application of UML 2.0 state diagrams to model
and reason about concurrent interactions
23Overview
- Programming model used to implement
multi-threaded concurrency - Threads
- Monitors
- Condition synchronization
- Application of UML 2.0 state diagrams to model
and reason about concurrent interactions
24Analytical models of behavior
- UML sequence diagrams useful for
- documentation/explanation
- roughing out a design prior to implementation
- But they are not very rigorous
- Depict only one scenario of interaction among
objects - Not good for reasoning about space of possible
behaviors - Such reasoning requires more formal and complete
models of behavior
25UML 2.0 State Models
- Used to model concurrent designs
- Abstract away much of the ugliness associated
with the multi-threaded programming model - Allow reasoning about space of behaviors of an
object and of concurrent, interacting objects - Key idea Each object modeled by a communicating
sequential process - Processes are inherently concurrent with one
another - Note Even a passive object is modeled by a
process - Processes communicate by sending and receiving
one-way, asynchronous signals - More complex modes of interaction (e.g.,
rendezvous) built atop the signaling facilities
26Key terms
- Event instantaneous occurrence at a point in
time - receipt of an asynchronous signal
- e.g., alarm raised, powered on
- onset of a condition
- e.g., paper tray becomes empty
- execution of some action or effect
- State behavioral condition that persists in time
- waiting for arrival of one or more asynchronous
signals and/or the onset of one or more
conditions - period during which some activity is being
performed - Transition instantaneous change in state
- triggered by an event
27State diagrams
- Graphical state-modeling notation
- States labeled roundtangles
- Transitions directed arcs, labeled by signal
occurrence, guard condition, and/or effects - Example
Event
signal(attribs) guard-condition / effect
S
T
States
Transition
28Events run to completion
- Run-to-completion semantics
- State machine processes one event at a time and
finishes all consequences of that event before
processing another event - Events do not interact with one another during
processing - Pool
- Where new incoming signals for an object are
stored until object is ready to process them - No arrival ordering assumed in the pool
29Example
C
S
C1
init / v 0
/ send S.init
S1
C2
seed(x) / v x
S2
/ send S.seed(100)
C3
/ send C.rand (v3)
seed(x) / v x
rand(x) x gt 1 / send S.seed(x/10)
30Modeling method invocations
- Given state machines for two objects C and S,
where C is the client and S the supplier of a
method m - Model the call as a signal that requests the
operation on behalf of the client - Model return as a reply from the supplier to the
client - C should send the request to S and then await the
reply - This protocol of interaction is called a
rendezvous
31UML 2.0 support for rendezvous
- UML implements rendezvous using
- Call activities, performed by the client
- Accept-call and reply actions, performed by the
supplier
32Example
C
S
S2 do/ v v3
reply (rand,v)
C1 do/ call S.seed(100)
/ accept-call (rand)
Idle
C2 do/ x call S.rand()
/ accept-call (seed(x))
S1 do/ v x
reply(seed)