![Page 1: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/1.jpg)
Concurrency/synchronization using UML state models and sequence models: A brief review
April 21st, 2008Michigan State University
![Page 2: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/2.jpg)
Simple monitor-process pattern
Idle
[guard] / accept-call ( op(parms) )
/ reply (op, result )
Monitor process
Operation body
![Page 3: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/3.jpg)
Bounded Buffer Example
/ reply ( pull, rv )
BoundedBuffer
Idle
[queue_.size != 0] / accept-call ( pull )
Pulling
do/ rv := queue_.pull
Pushingdo/ queue_.push(x)
/ reply ( push )
[queue_.size != MAX] / accept-call ( push(x) )
![Page 4: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/4.jpg)
Example: Code for Buffer::push
void Buffer::push(int x)
{
lock_.acquire();
while (queue_.size() == MAX) {
full_.wait();
}
queue_.push(x);
empty_.signal();
lock_.release();
}
Idle
[queue_.size() != MAX]/ accept-call (push(x))
Pushingdo/ queue_.push(x)
/ reply (push)
![Page 5: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/5.jpg)
Example: Code for Buffer::push
void Buffer::push(int x)
{
lock_.acquire();
while (queue_.size() == MAX) {
full_.wait();
}
queue_.push(x);
empty_.signal();
lock_.release();
}
Idle
[queue_.size() != MAX]/ accept-call (push(x))
Pushingdo/ queue_.push(x)
/ reply (push)
![Page 6: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/6.jpg)
Example: Code for Buffer::push
void Buffer::push(int x)
{
lock_.acquire();
while (queue_.size() == MAX) {
full_.wait();
}
queue_.push(x);
empty_.signal();
lock_.release();
}
Idle
[queue_.size() != MAX]/ accept-call (push(x))
Pushingdo/ queue_.push(x)
/ reply (push)
![Page 7: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/7.jpg)
Example: Code for Buffer::push
void Buffer::push(int x)
{
lock_.acquire();
while (queue_.size() == MAX) {
full_.wait();
}
queue_.push(x);
empty_.signal();
lock_.release();
}
Idle
[queue_.size() != MAX]/ accept-call (push(x))
Pushingdo/ queue_.push(x)
/ reply (push)
![Page 8: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/8.jpg)
Example: Code for Buffer::pull
int Buffer::pull(){ lock_.acquire();
while (queue_.size() == 0) { empty_.wait(); }
int rv = queue_.pull();
full_.signal(); lock_.release(); return rv;}
Idle
[queue_.size() != 0]/ accept-call (pull)
Pushingdo/ rv :=
queue_.pull()
/ reply (pull, rv)
![Page 9: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/9.jpg)
More complex guard conditions
Consider a banking application that allows multiple clients to deposit and withdraw funds from shared accountsGoals: Protect against data races, so that money is
not accidentally created or destroyed Prevent overdrafts by making withdraw
requests block if account has insufficient funds
Question: How should we model the behavior of an account object?
![Page 10: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/10.jpg)
Monitor-process model of BankAccount
/ reply ( deposit )
BankAccount
Idle
/ accept-call ( deposit(amount) )
Depositingdo/ balance_ += amount;
Withdrawingdo/ balance_ -= amount;
/ reply ( withdraw )
[ amount <= balance_ ] / accept-call ( withdraw(amount) )
![Page 11: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/11.jpg)
Code for BankAccount::withdraw
void
BankAccount::withdraw(int amount)
{
lock_.acquire();
while (amount > balance_) {
okToWithdraw_.wait();
}
balance_ -= amount;
lock_.release();
}
Idle
[amount <= balance_]/ accept-call (withdraw(amount))
Withdrawing
do/ balance_ -= amount;
/ reply (withdraw)
![Page 12: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/12.jpg)
Code for BankAccount::deposit
void
BankAccount::deposit(int amount)
{
lock_.acquire();
balance_ += amount;
okToWithdraw_.broadcast();
lock_.release();
}
Idle/ accept-call (deposit(amount))
Depositing
do/ balance_ += amount;
/ reply (deposit)
![Page 13: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/13.jpg)
Signal vs. BroadcastWhen one thread changes the value of a condition upon which others might be waiting, the modifier is obliged to notify these waiting threadsAlways safest, though perhaps not very efficient, to use broadcast to notify waiting threads after a changeQuestion: When is it safe to use signal?
![Page 14: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/14.jpg)
“Mixed” Monitor objects
Some methods on a monitor class may be “non-monitor methods” Do not acquire / release mutex lock Multiple threads may access
simultaneously Threads may access non-monitor
methods while 1 thread in a monitor method
1 thread may enter monitor method while other threads in non-monitor method
![Page 15: Concurrency/synchronization using UML state models and sequence models: A brief review April 21 st, 2008 Michigan State University](https://reader030.vdocument.in/reader030/viewer/2022032611/56649d635503460f94a459a7/html5/thumbnails/15.jpg)