Programmazione concorrente:
Programmazione concorrente:
Java e Ada
Java e Ada
Paolo Costa
Paolo Costa
2
Concurrency
Concurrency
µµ Concurrency is an important area of computer science studied in Concurrency is an important area of computer science studied in different contexts: machine architectures, operating systems,
different contexts: machine architectures, operating systems,
distributed systems, database, etc
distributed systems, database, etc
µ
µ Objects provide a way to divide a program into independent Objects provide a way to divide a program into independent sections. Often, you also need to turn a program into separate,
sections. Often, you also need to turn a program into separate,
independently running subtasks
independently running subtasks
µ
µ Concurrency may be Concurrency may be physicalphysical ((parallelismparallelism) if each unit is executed ) if each unit is executed on a dedicated processor or
on a dedicated processor or logicallogical if the CPU is able to switch if the CPU is able to switch from one to another so that all units appear to progress
from one to another so that all units appear to progress
simultaneously
3
3 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Process & Thread
Process & Thread
µ
µ
A
A
process
process
is a self-
is a self
-contained running program with
contained running program with
its own address space
its own address space
µµ
A
A
multitasking
multitasking
operating system is capable of
operating system is capable of
running more than one process at a time by
running more than one process at a time by
periodically switching the CPU from one task to
periodically switching the CPU from one task to
another
another
µµ
The term
The term
thread
thread
(a.k.a. lightweight process)
(a.k.a. lightweight process)
instead
instead
is used when the concurrent units share a single
is used when the concurrent units share a single
address space
address space
4
Cooperation
Cooperation
µ
µ
If the abstract machine does not support
If the abstract machine does not support
concurrency, it can be simulated by transferring
concurrency, it can be simulated by transferring
control explicitly from one unit to another
control explicitly from one unit to another
(
(
coroutines
coroutines
) according to a cooperative model
) according to a cooperative model
µµ
Runtime support is simpler to implement but it is
Runtime support is simpler to implement but it is
more error prone:
more error prone:
the programmer has to handle cooperation: bugs in
the programmer has to handle cooperation: bugs in
code may lock the systems
5
5 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Preemption
Preemption
µ
µ
Modern systems adopts a
Modern systems adopts a
preemptive
preemptive
model
model
µ
µ
Preemption is an action performed by the
Preemption is an action performed by the
underlying implementation: it forces a process to
underlying implementation: it forces a process to
abandon its running state even if it could safely
abandon its running state even if it could safely
execute
execute
µµ
Usually a time slicing mechanism is employed where
Usually a time slicing mechanism is employed where
a process is suspend when a specified amount of
a process is suspend when a specified amount of
time has expired
time has expired
6
Concurrency in Java
Concurrency in Java
µ
µ
Java supports concurrency at
Java supports concurrency at
language
language
level
level
rather
rather
than through run time libraries (like POSIX threads
than through run time libraries (like POSIX threads
for C/C++)
for C/C++)
µµ
It employs a
It employs a
preemptive
preemptive
model
model
µ
µ
If time
If time
-
-
slicing is available (implementation
slicing is available (implementation
dependent), Java ensures equal priority threads
dependent), Java ensures equal priority threads
execute in round
execute in round
-
-
robin fashion otherwise they runs
robin fashion otherwise they runs
to completion
to completion
µµ
Priority is handled differently according to the
Priority is handled differently according to the
specific implementation
specific implementation
7
7 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Thread
Thread
Class
Class
µ
µ The simplest way to create a thread is to inherit from The simplest way to create a thread is to inherit from java.lang.Thread
java.lang.Thread, which has all the wiring necessary to create , which has all the wiring necessary to create and run threads. The most important method for
and run threads. The most important method for ThreadThread is is run()run()
class MyThread extends Thread { private String message;
public MyThread(String m) {message = m;} public void run() {
for(int r=0; r<20; r++)
System.out.println(message); }
}
public class ProvaThread {
public static void main(String[] args) { MyThread t1,t2;
t1=new MyThread("primo thread"); t2=new MyThread("secondo thread"); t1.start();
t2.start(); }
}
The thread object is defined by extending Thread class
Thread object is instantiated as usual through a new()
To run the thread you must invoke the start()
method on it
You must override run(),
to make the thread do your bidding.
8
Runnable
Runnable
Interface
Interface
µ
µ You can use the alternative approach of implementing the You can use the alternative approach of implementing the RunnableRunnable
interface.
interface. RunnableRunnable specifies only that there be a specifies only that there be a run()run() method method
implemented, and
implemented, and ThreadThread also implements also implements RunnableRunnable
class MyThread implements Runnable { private String message;
public MyThread(String m) {message = m;} public void run() {
for(int r=0; r<20; r++)
System.out.println(message); }
}
public class ProvaThread {
public static void main(String[] args) { Thread t1, t2;
MyThread r1, r2;
r1 = new MyThread("primo thread"); r2 = new MyThread("secondo thread"); t1 = new Thread(r1); t2 = new Thread(r2); t1.start(); t2.start(); } }
Your class must implement
Runnable interfaces
start() method is invoked
to execute the thread
run() must be overridden
To produce a thread from a
Runnable object, you must
create a separate Thread object
9
9 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
sleep
sleep
()
()
µ
µ
Causes the currently executing thread to sleep
Causes the currently executing thread to sleep
(temporarily cease execution) for the specified
(temporarily cease execution) for the specified
number of milliseconds.
number of milliseconds.
µµ
The thread does not
The thread
does not
lose ownership of any monitors
lose ownership of any monitors
(see next).
(see next).
µµ
Useful for:
Useful for:
Periodic actions
Periodic actions
Need to wait for some period of time before doing the Need to wait for some period of time before doing the action again.
action again.
10
join()
join()
µ
µ
The
The
join()
join()
method used to wait until thread is
method used to wait until thread is
done.
done.
µµ
The caller of
The caller of
join()
join()
blocks until thread finishes.
blocks until thread finishes.
µµ
Other versions of join take in a timeout value.
Other versions of join take in a timeout value.
If thread doesn
If thread doesn
’
’
t finish before timeout, join returns.
t finish before timeout, join returns.
µ
µ
Alternatively, can check on a thread with
Alternatively, can check on a thread with
isAlive
isAlive
:
:
11
11 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Non
Non
-
-
determinism
determinism
µ
µ
Threads execution proceeds without a predefined
Threads execution proceeds without a predefined
order
order
µµ
The same code, if run on different computers, could
The same code, if run on different computers, could
produce different output
produce different output
it depends on how internal scheduling is performed,
it depends on how internal scheduling is performed,
on processor features,
on processor features,
…
…
µ
µ
Such behavior is define as
Such behavior is define as
non
non
-
-
deterministic
deterministic
µ
µ
Non
Non
-
-
determinism is a key point
determinism is a
key point
in concurrency
in concurrency
12
Correctness
Correctness
µµ A concurrent system is correct if and only if it owns the A concurrent system is correct if and only if it owns the following properties:
following properties:
Safety
Safety
: bad things do not happen: bad things do not happen
Liveness
Liveness
: good things eventually happen: good things eventually happenµ
µ Safety failures lead to unintended behavior at run time Safety failures lead to unintended behavior at run time ——
things just start going wrong
things just start going wrong
Read / write conflictsRead / write conflicts
Write / write conflictsWrite / write conflicts
µ
µ LivenessLiveness failures lead to no behavior failures lead to no behavior —— things just stop runningthings just stop running
lockinglocking waitingwaiting I/OI/O
CPU contentionCPU contention
failurefailure
µ
µ Sadly enough, some of the easiest things you can do to improve Sadly enough, some of the easiest things you can do to improve liveness
liveness properties can destroy safety properties, and vice properties can destroy safety properties, and vice versa (e.g. locking)
13
13 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Synchronization
Synchronization
µ
µ Imagine you have two threads, one thread named "Imagine you have two threads, one thread named "redred" and another " and another
named "blue". Both threads are trying to set their color of the
named "blue". Both threads are trying to set their color of the same same
RGBColor
RGBColor objectobject
µ
µ If the thread scheduler interleaves these two threads in just thIf the thread scheduler interleaves these two threads in just the right e right
way, the two threads will inadvertently interfere with each othe
way, the two threads will inadvertently interfere with each other, r, yielding a write/write conflict. In the process, the two threads
yielding a write/write conflict. In the process, the two threads will will corrupt the object's state
corrupt the object's state
public class RGBColor { private int r;
private int g; private int b;
public void setColor(int r, int g, int b) { checkRGBVals(r, g, b); this.r = r; this.g = g; this.b = b; } from http://www.javaworld.com/jw-08-1998/jw-08-techniques-p2.html
14
Synchronization
Synchronization
µ
µ
Typical issue in concurrent programming
Typical issue in concurrent programming
class Even {private int n = 0; public int next(){
// POST?: next is always even ++n;
++n;
return n; }
}
15
15 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Objects and Locks
Objects and Locks
µ
µ
Every instance of class
Every instance of class
Object
Object
and its subclasses
and its subclasses
possess a lock
possess a lock
µµ
Scalar fields can be locked only via their enclosing
Scalar fields can be locked only via their enclosing
objects
objects
µµ
Locking may be applied only to the use of fields
Locking may be applied only to the use of fields
within methods
within methods
µµ
Locking an array of
Locking an array of
Object
Object
does not automatically
does not automatically
lock all its elements
16
Synchronized Blocks and Methods
Synchronized Blocks and Methods
µ
µ
Block synchronization takes an argument of which
Block synchronization takes an argument of which
object to lock
object to lock
µ
µ
Declaring a method as
Declaring a method as
synchronized
synchronized
would
would
preclude conflicting traces. Locking serializes the
preclude conflicting traces. Locking serializes the
execution of
execution of
synchronized
synchronized
methods
methods
synchronized void f() { /* body */ } synchronized void f() { /* body */ }
is equivalent to
is equivalent to
void f() {
void f() { synchronized(thissynchronized(this) { /* body */ } }) { /* body */ } } synchronized (object){
// Lock is held …
}
17
17 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Acquiring Locks
Acquiring Locks
µµ A lock is acquired A lock is acquired automaticallyautomatically on entry to a on entry to a synchronizedsynchronized
method or block, and released on exit, even if the exit occurs
method or block, and released on exit, even if the exit occurs
due to an exception
due to an exception
µ
µ Locks operate on a perLocks operate on a per--thread, not perthread, not per--invocation basis. A invocation basis. A thread hitting synchronized passes if the lock is free or the
thread hitting synchronized passes if the lock is free or the
thread already possess the lock, otherwise it blocks
thread already possess the lock, otherwise it blocks
µ
µ A synchronized method or block obeys the acquireA synchronized method or block obeys the acquire--release release
protocol only with respect to other synchronized methods and
protocol only with respect to other synchronized methods and
blocks on the same target object
blocks on the same target object
methods that are not synchronized may still execute at methods that are not synchronized may still execute at
any time, even if a synchronized method is in progress
any time, even if a synchronized method is in progress
µ
µ Synchronized is not equivalent to atomic, but synchronization Synchronized is not equivalent to atomic, but synchronization can be used to achieve atomicity
18
synchronized
synchronized
& 00
& 00
µ
µ The The synchronizedsynchronized keyword is not considered to be part of a keyword is not considered to be part of a
method's signature:
method's signature:
the synchronizedthe
synchronized
modifier is modifier is notnot automatically inherited automatically inheritedwhen subclasses override
when subclasses override superclasssuperclass methodsmethods
methods in interfaces cannot be declared as synchronizedmethods in interfaces cannot be declared as
synchronized
µµ Synchronization in an inner class method is independent of its oSynchronization in an inner class method is independent of its outer uter
class
class
however, a nonhowever, a non--static inner class method can lock its containing static inner class method can lock its containing
class, say
class, say OuterClass
OuterClass
, via code blocks using:, via code blocks using: synchronized(OuterClass.thissynchronized(OuterClass.this) { /* body */ }) { /* body */ }
µ
µ Static synchronization employs the lock possessed by the Static synchronization employs the lock possessed by the ClassClass
object associated with the class the static methods are declared
object associated with the class the static methods are declared in. in.
The static lock for class The static lock for class CC can also be accessed inside instance can also be accessed inside instance
methods via:
methods via:
synchronized(C.class
19
19 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Key Rules
Key Rules
I.
I. Always lock during updates to object fieldsAlways lock during updates to object fields
synchronized (point) { synchronized (point) { point.x point.x = 5;= 5; point.y point.y = 7; }= 7; } II.
II. Always lock during access of possibly updated object fieldsAlways lock during access of possibly updated object fields
synchronized(point synchronized(point) {) { if(point.x if(point.x > 0) {> 0) { ... ... }} }} III.
III. You do not need to synchronize stateless parts of methodsYou do not need to synchronize stateless parts of methods
IV.
IV. Never lock when invoking methods on other objectsNever lock when invoking methods on other objects
public synchronized void service(){ state = ...; // update state
operation(); }
public void service(){ synchronized(this) {
state = ...; // update state }
operation(); }
public synchronized void service(){ ...
h.foo(); }
public void service(){ synchronized(this) {
state = ...; // update state }
20
Deadlock
Deadlock
µ
µ Deadlock is possible when two or more objects are mutually Deadlock is possible when two or more objects are mutually accessible from two or more threads, and each thread holds
accessible from two or more threads, and each thread holds
one lock while trying to obtain another lock already held by
one lock while trying to obtain another lock already held by
another thread
another thread
µ
µ Although fully synchronized atomic objects are always safe, Although fully synchronized atomic objects are always safe, they may lead to deadlock
21
21 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Tema
Tema
d
d
’
’
esame
esame
6
6
maggio
maggio
2005
2005
µ
µ Consider the following java classes:Consider the following java classes:
µ
µ How deadlock can arise if two thread, say X and Y, How deadlock can arise if two thread, say X and Y, concurrently access to A and B respectively ?
concurrently access to A and B respectively ?
µ
µ How can you effectively solve the issue ?How can you effectively solve the issue ?
class A {
...
synchronized public void ma1(B b) {
...
b.mb2(); }
synchronized public void ma2() { ...
} }
class B {
...
synchronized public void mb1(A a) {
...
a.ma2(); }
synchronized public void mb2() { ...
} }
22
Condition Synchronization
Condition Synchronization
µ
µ A controller is required for a A controller is required for a carparkcarpark, which only permits cars , which only permits cars to enter when the
to enter when the carparkcarpark is not full and does not permit cars is not full and does not permit cars to leave when there are no cars in the
to leave when there are no cars in the carparkcarpark
µ
µ Car arrival and departure are simulated by separate threadsCar arrival and departure are simulated by separate threads
23
23 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
CarParkControl
CarParkControl
Monitor
Monitor
class
CarParkControl {
protected
int spaces;
protected
int capacity;
CarParkControl(int n)
{capacity = spaces = n;}
synchronized
void arrive() {
…
--spaces; …
}
synchronized
void depart() {
… ++spaces; …
}
}
condition
synchronization
?
block if full?
(spaces==0)
block if
empty?
(spaces==N)
mutual exclusion
by synch
methods
24
Condition Synchronization in
Condition Synchronization in
Java
Java
µµ
Java provides a thread wait set per monitor
Java provides a thread wait set per monitor
(actually per object) with the following methods:
(actually per object) with the following methods:
public final
void notify()
Wakes up a single thread that is waiting on this object's set
public final
void notifyAll()
Wakes up all threads that are waiting on this object's set
public final
void wait()
throws
InterruptedException
Waits to be notified by another thread. The waiting threa releases the synchronization lock associated with the monitor. When notified, the thread must wait to reacquire the monitor before resuming execution
25
25 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Condition Synchronization
Condition Synchronization
µ
µ The The whilewhile loop is necessary to retest the condition loop is necessary to retest the condition condcond to ensure to ensure
that
that condcond is indeed satisfied when it reis indeed satisfied when it re--enters the monitorenters the monitor
µ
µ notifyAllnotifyAll is necessary to awaken other is necessary to awaken other thread(sthread(s) that may be ) that may be
waiting to enter the monitor now that the monitor data has been
waiting to enter the monitor now that the monitor data has been
changed
changed
when
cond
act -> NEWSTAT
Java:
public synchronized
void act()
throws
InterruptedException {
while
(
!cond
) wait();
// modify monitor data
notifyAll()
26
Condition Synchronization
Condition Synchronization
class CarParkControl {
protected int spaces;
protected int capacity;
CarParkControl(int n)
{capacity = spaces = n;}
synchronized void arrive() throws InterruptedException {
while (spaces==0) wait();
--spaces; notify(); }
synchronized void depart() throws InterruptedException {
while (spaces==capacity) wait();
++spaces; notify(); }
}
Why is it safe to use notify()
27
27 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Single Notifications
Single Notifications
µ
µ
You can reduce the context
You can reduce the context
-switch overhead
-
switch overhead
associated with notifications by using a single
associated with notifications by using a single
notify
notify
rather than
rather than
notifyAll
notifyAll
µµ
Single notifications can be used to improve
Single notifications can be used to improve
performance when you are sure that at most one
performance when you are sure that at most one
thread needs to be woken. This applies when:
thread needs to be woken. This applies when:
all possible waiting threads are necessarily waiting for
all possible waiting threads are necessarily waiting for
conditions relying on the same notifications, usually
conditions relying on the same notifications, usually
the exact same condition
the exact same condition
each notification intrinsically enables at most a single
each notification intrinsically enables at most a single
thread to continue. Thus it would be useless to wake
thread to continue. Thus it would be useless to wake
up others
28
Summary
Summary
µµ Each guarded action in the model of a monitor is implemented Each guarded action in the model of a monitor is implemented as a synchronized method which uses a while loop and wait()
as a synchronized method which uses a while loop and wait()
to implement the guard
to implement the guard
µ
µ Changes in the state of the monitor are Changes in the state of the monitor are signaledsignaled to waiting to waiting threads using
threads using notify()notify() or or notifyAll()notifyAll()
µ
µ The monitor is referred to the object instance which is used to The monitor is referred to the object instance which is used to communicate among Threads
communicate among Threads
µ
µ The lock must always be acquired before wait is invoked:The lock must always be acquired before wait is invoked:
syncronized(lock syncronized(lock) {) { ... ... lock.wait lock.wait();(); } } µ
µ Always reAlways re--check condition, after a wait:check condition, after a wait:
syncronized(lock
syncronized(lock) { ) { syncronized(locksyncronized(lock) { ) { while(!cond
while(!cond) {) { if(!condif(!cond) {) { lock.wait
lock.wait();(); lock.waitlock.wait();(); } } } } } } }} YES YES NONO
29
29 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Busy Waits
Busy Waits
µ
µ
Implementing guards via waiting and notification
Implementing guards via waiting and notification
methods is nearly always superior to using an
methods is nearly always superior to using an
optimistic
optimistic
-
-
retry-
retry
-style busy
style busy-
-
wait "
wait "
spinloop
spinloop
" of the
" of the
form:
form:
protected void
protected void busyWaitUntilCondbusyWaitUntilCond() { () { while (!
while (!condcond) ) Thread.yield
Thread.yield(); }(); }
µ
µ
Reasons are:
Reasons are:
Efficiency
Efficiency
Scheduling
Scheduling
Triggering
Triggering
Synchronizing actions
Synchronizing actions
30
sleep
sleep
()
()
µ
µ
Causes the currently executing thread to sleep
Causes the currently executing thread to sleep
(temporarily cease execution) for the specified
(temporarily cease execution) for the specified
number of milliseconds
number of milliseconds
µµ
The thread
The thread
does not
does not
lose ownership of any monitors
lose ownership of any monitors
µ
µ
Useful for:
Useful for:
periodic actions
periodic actions
need to wait for some period of time before doing the need to wait for some period of time before doing the action again.
action again.
31
31 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
initial
running blocked
stopped
wait waits for lock
start run method finished lock is given to Thread waiting ready sleeping sleep Thread gets its time slice Thread loses time slice time has elapsed notify() notifyAll()
A Thread can only be started once; if a Thread has stopped (reached
the end of its run), nothing can happen anymore to the Thread.
Transition States
32
Task
Task
Syncronization
Syncronization
in
in
Ada
Ada
• Free Ada compiler
33
33 Informatica 3
34
A Guardian Task
35
35 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Semantica
Semantica
dei
dei
rendez
rendez
-
-
vous
vous
1) chiamata ad ENTRY (analoghe a chiamata di procedura)
2) il task chiamato deve fare una ACCEPT -> rendezvous
Di solito task body usa costrutto SELECT per decidere se e quando accettare. SELECT WHEN C1 => PRG1 OR WHEN C2 => PRG2 OR PRG3 -- sempre aperta ELSE PRG4 END SELECT;
- C1 e C2 sono alternative APERTE <=> C1, C2 = true
- PRGk puo` contenere ACCEPT o DELAY
1) esegui se esiste PRGk con Ck aperta e contenente una ACCEPT
2) se non esiste, allora esegui PRGk' con Ck' aperta e DELAY (il piu`
piccolo DELAY aperto)
3) se tutto chiuso, esegui ramo ELSE. Se non c'e` ELSE, sospendi in
36
Tema
Tema
d
d
’
’
esame
esame
µ
µ Si consideri un conto corrente bancario possono accedere in Si consideri un conto corrente bancario possono accedere in modo concorrente per effettuare operazioni di versamento e di
modo concorrente per effettuare operazioni di versamento e di
prelievo.
prelievo.
ÈÈ definito un importo massimo prelevabile, e ldefinito un importo massimo prelevabile, e l’’accesso al accesso al
conto corrente da parte di un utente che vuole effettuare
conto corrente da parte di un utente che vuole effettuare
un prelievo
un prelievo èè possibile solo se, nel conto corrente possibile solo se, nel conto corrente èè
presente un importo tale da rendere possibile il prelievo
presente un importo tale da rendere possibile il prelievo
della cifra massima senza
della cifra massima senza ““andare in rossoandare in rosso””
LL’’accesso allaccesso all’’utente che vuole effettuare un prelievo utente che vuole effettuare un prelievo èè
permesso se l
permesso se l’’importo che si intende prelevare importo che si intende prelevare èè inferiore inferiore all
all’’attuale disponibilitattuale disponibilitàà
µ
µ Si dica quali delle soluzioni applicative (a) o (b) sono Si dica quali delle soluzioni applicative (a) o (b) sono realizzabili con semplici programmi in Ada o in Java,
realizzabili con semplici programmi in Ada o in Java,
motivando sinteticamente la risposta nel caso negativo.
37
37 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Soluzione
Soluzione
Java (1)
Java (1)
public class ContoCor {private int disponibile; private int soglia;
ContoCor () {... disponibile=0; soglia=2000; ...}
public synchronized void deposita(int importo){ disponibile += importo;
notifyAll(); }
public synchronized void ritira(int importo){ while (!(disponibile >= soglia) ) try { wait(); }
catch(InterruptedException e) {} disponibile -= importo;
} }
38
Soluzione
Soluzione
Ada
Ada
(1)
(1)
task ContoCor isentry deposita(importo: in INTEGER); entry ritira(importo: in INTEGER); end ContoCor;
task body ContoCor is
disponibile: INTEGER := 0; soglia := 2000; loop
select
when disponibile >= soglia
accept ritira(importo: in INTEGER) do disponibile := disponibile – importo; end ritira;
or
when true
accept deposita(importo: in INTEGER) do disponibile := disponibile + importo; end deposita;
end select; end loop; end ContoCor;
39
39 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Soluzione
Soluzione
Java (2)
Java (2)
public class ContoCor {... TUTTO COME SOPRA ...
public synchronized void ritira(int importo){ while (!(disponibile >= importo) ) try { wait(); }
catch(InterruptedException e) {} disponibile -= importo;
} }
40
Soluzione
Soluzione
Ada
Ada
(2)
(2)
µ
µ
In Ada non esiste una semplice variante del caso (b)
In Ada non esiste una semplice variante del caso (b)
perch
perch
é
é
nella clausola
nella clausola
when
when
di una
di una
select
select
non è
non
è
possibile valutare il parametro della entry citata
possibile valutare il parametro della entry citata
nella corrispondente
nella corrispondente
accept;
accept
;
µµ
il valore del parametro risulta noto solo DOPO
il valore del parametro risulta noto solo DOPO
l
l
’
’
esecuzione della
esecuzione della
accept
accept
e quindi non può essere
e quindi non può essere
utilizzato per decidere l
utilizzato per decidere l
’
’
esecuzione dell’
esecuzione dell
’
accept
accept
stessa.
41
41 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Esercizio
Esercizio
Thread/Task
Thread/Task
µ
µ Si realizzi in Java e in Ada il seguente sistema. Si realizzi in Java e in Ada il seguente sistema.
Il modulo PI esegue ripetutamente le seguenti operazioni: Il modulo PI esegue ripetutamente le seguenti operazioni:
legge da tastiera una coppia di valori <i,
legge da tastiera una coppia di valori <i, chch>, dove i >, dove i èè un un numero tra 0 e 3,
numero tra 0 e 3, chch un carattere, e inserisce il carattere un carattere, e inserisce il carattere ch
ch nel buffer i (ognuno dei quattro buffer contiene al pinel buffer i (ognuno dei quattro buffer contiene al piùù un carattere).
un carattere).
Il modulo PO considera a turno in modo circolare i quattro Il modulo PO considera a turno in modo circolare i quattro
buffer e preleva il carattere in esso contenuto, scrivendo in
buffer e preleva il carattere in esso contenuto, scrivendo in
uscita la coppia di valori <i,
uscita la coppia di valori <i, chch> se ha appena prelevato il > se ha appena prelevato il carattere
carattere chch dal buffer i. dal buffer i.
LL’’accesso a ognuno dei buffer accesso a ognuno dei buffer èè in mutua esclusione; PI in mutua esclusione; PI
rimane bloccato se il buffer a cui accede
rimane bloccato se il buffer a cui accede èè pieno, PO se pieno, PO se èè vuoto.
42
Esercizio
Esercizio
Thread/Task (contd.)
Thread/Task (contd.)
0 1 2 3 PI PO µ
µ Data la seguente sequenza di valori letta da PI, scrivere la Data la seguente sequenza di valori letta da PI, scrivere la sequenza scritta in corrispondenza da PO.
sequenza scritta in corrispondenza da PO.
<1, c> <0, b> <2, m> <0, f> <1, h> <3, n>
<1, c> <0, b> <2, m> <0, f> <1, h> <3, n>
µ
43
43 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Esercizio
Esercizio
Thread/Task (contd.)
Thread/Task (contd.)
0 1 2 3 PI PO µ
µ Descrivere brevemente in quali casi si può verificare una Descrivere brevemente in quali casi si può verificare una situazione di
situazione di deadlockdeadlock tra PI e PO. Illustrare con un semplice tra PI e PO. Illustrare con un semplice esempio.
esempio.
µ
44
44 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Java
Java
public class Buf { private char q;
private boolean full; Buf() {
full = false; }
public synchronized void put (char item) { while (full) try { wait(); } catch (InterruptedException e) { } q = item; full = true; notify(); }
public synchronized char get () { while (!full) try { wait(); } catch (InterruptedException e) { } full = false; notify(); return q; }
45
45 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
public class Pi extends Thread { private Buf[] buff;
private String[] commands; Pi (Buf[] b, String[] c) {
buff = b; commands = c; }
public void run() {
for(int i=0; i < commands.length; i++)
buff[(int)commands[i].charAt(0)-(int)'0']. put(commands[i].charAt(2)); } }
Task Pi
Task Pi
46
public class Po extends Thread { private Buf[] buff;
Po (Buf[] b) { buff = b; }
public void run() { while(true) {
for(int i=0; i < buff.length; i++)
System.out.println("Buff "+i+":"+buff[i].get()); } } }
Task Po
Task Po
47
47 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006
Main
Main
public class pi_po {
public static void main (String [] args){
Buf[] bfs = new Buf[4]; Pi pi0; Po po0; bfs[0] = new Buf(); bfs[1] = new Buf(); bfs[2] = new Buf(); bfs[3] = new Buf();
pi0 = new Pi(bfs, args); po0 = new Po(bfs);
pi0.start(); po0.start(); }
48
ADA
ADA
task body BUF is Q : CHARACTER;FULL : BOOLEAN := FALSE; begin
loop select
when not FULL =>
accept PUT(X: in CHARACTER) do Q := X;
FULL := TRUE; end PUT;
or
when FULL =>
accept GET(X: out CHARACTER) do X := Q; FULL := FALSE; end GET; end select; end loop; end BUF;
49
49 Informatica 3
Informatica 3 --a.a. 2005a.a. 2005--20062006 task body PI is B : INTEGER; V : CHARACTER; begin loop TEXT_IO.PUT("Buff? >"); Ada.Integer_Text_IO.GET(B); TEXT_IO.PUT("Char? >"); TEXT_IO.GET(V); TEXT_IO.PUT_LINE(" "); BFS(B).PUT(V); end loop; end PI;
Task Pi
Task Pi
50
Task Po
Task Po
task body PO isI : INTEGER := 0; V : CHARACTER; begin loop for I in 0..3 loop BFS(I).GET(V); Ada.Integer_Text_IO.PUT(I); TEXT_IO.PUT(":"); TEXT_IO.PUT(V); TEXT_IO.PUT_LINE(" "); end loop; end loop; end PO; begin -- corpo null; end PI_PO;