Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Systems: Chapter 5
Internals Concurrency:
and Design
Principles Mutual Exclusion
and Synchronization
Eighth Edition
By William Stallings
OperatingSystem design is concerned
with the management of processes and
threads:
Multiprogramming
Multiprocessing
Distributed Processing
Multiple
Applications
Structured
Applications Operating
invented to allow System
processing time to Structure
be shared among extension of
active applications modular design
and structured
programming OS themselves
implemented as a
set of processes
or threads
Table 5.1
Some Key
Terms
Related
to
Concurrency
Interleaving and overlapping
can be viewed as examples of concurrent processing
both present the same problems
Hardware approaches
Special purpose machine instructions
Adv of reducing overhead
If one process fails outside the critical section, other process is not blocked. But if it
fails within the critical section or after setting the flag then it blocks the other process
Third attempt
There is no way to
know which process You don’t know
There is no way to
will continue whether another
know before a
immediately on a process is waiting so
process decrements a
uniprocessor system the number of
semaphore whether
when two processes unblocked processes
it will block or not
are running may be zero or one
concurrently
Semaphore Primitives
A queue is used to hold processes waiting on the semaphore
Strong Semaphores
• the process that has been blocked the longest is
released from the queue first (FIFO)
Weak Semaphores
• the order in which processes are removed from the
queue is not specified
Binary Semaphore Primitives
Example of Semaphore Mechanism
Example of Semaphore Mechanism
Mutual Exclusion Using Semaphores
Processes Using Semaphore
Producer/Consumer Problem
out in
A Correct
Solution to the
Infinite-Buffer
Producer/Cons
umer Problem
Using Binary
Semaphores
/* program producerconsumer */
semaphore n = 0, s = 1;
void producer()
Figure 5.11 {
while (true) {
produce();
A Solution semWait(s);
append();
to the semSignal(s);
Infinite- semSignal(n);
Buffer }
}
Producer/ void consumer()
Consumer {
while (true) {
Problem semWait(n);
Using semWait(s);
Semaphores take();
semSignal(s);
consume();
}
}
void main()
{
parbegin (producer, consumer);
}
Producer
• producer:
while (true) {
/* produce item v */
b[in] = v;
in++;
}
Consumer
• consumer:
while (true) {
while (in <= out)
/*do nothing */;
w = b[out];
out++;
/* consume item w */
}
Circular Buffer
Figure 5.13
A Solution to
the Bounded-
Buffer
Producer/Cons
umer Problem
Using
Semaphores
Implementation of
Semaphores
Imperativethat the semWait and
semSignal operations be implemented as
atomic primitives
Can be implemented in hardware or firmware
Software schemes such as Dekker’s or
Peterson’s algorithms can be used
Useone of the hardware-supported
schemes for mutual exclusion
Figure 5.14
Two Possible Implementations of Semaphores
semWait(s) semWait(s)
{ {
while (compare_and_swap(s.flag, 0 , 1) == 1) inhibit interrupts;
/* do nothing */; s.count--;
s.count--; if (s.count < 0) {
if (s.count < 0) { /* place this process in s.queue */;
/* place this process in s.queue*/; /* block this process and allow interrupts */;
/* block this process (must also set s.flag to 0) }
*/; else
} allow interrupts;
s.flag = 0; }
}
semSignal(s)
semSignal(s) {
{ inhibit interrupts;
while (compare_and_swap(s.flag, 0 , 1) == 1) s.count++;
/* do nothing */; if (s.count <= 0) {
s.count++; /* remove a process P from s.queue */;
if (s.count <= 0) { /* place process P on ready list */;
/* remove a process P from s.queue */; }
/* place process P on ready list */; allow interrupts;
} }
s.flag = 0;
}
MONITOR
cwait(c1)
condition variables
Procedure 1
condition cn
cwait(cn)
Procedure k
urgent queue
csignal
initialization code
Exit
A Solution to the
Bounded-Buffer
Producer/Consu
mer Problem
Using a Monitor
When processes interact with one another two
fundamental requirements must be satisfied:
synchronization communication
Table 5.5
Design Characteristics of Message Systems for
Interprocess Communication and Synchronization
Bothsender and receiver are blocked until
the message is delivered
Sometimes referred to as a rendezvous
Allowsfor tight synchronization between
processes
Nonblocking Send
Nonblocking send, blocking receive
• sender continues on but receiver is blocked until the
requested message arrives
• most useful combination
• sends one or more messages to a variety of destinations as
quickly as possible
• example -- a service process that exists to provide a service
or resource to other processes
Direct Indirect
addressing addressing
Direct Addressing
Send primitive includes a specific identifier
of the destination process
Receive primitive can be handled in one of
two ways:
require that the process explicitly
designate a sending process
effective for cooperating concurrent processes
implicit addressing
source parameter of the receive primitive possesses a
value returned when the receive operation has been
performed
Indirect Addressing
S1 Mailbox R1 Port R1
Sn
R1 S1 R1
S1 Mailbox Mailbox
Rm Sn Rm
A Solution to
the
Readers/Write
rs Problem
Using
Semaphores:
Readers Have
Priority
Readers only in the system •wsem set
•no queues
Both readers and writers with read first •wsem set by reader
•rsem set by writer
•all writers queue on wsem
•one reader queues on rsem
•other readers queue on z
Both readers and writers with write first •wsem set by writer
•rsem set by writer
•writers queue on wsem
•one reader queues on rsem
•other readers queue on z
Table 5.6
State of the Process Queues for Program of Figure 5.23
Figure 5.23
A Solution to the
Readers/Writers
Problem Using
Semaphores:
Writers Have
Priority
void reader(int i) void controller()
{ {
message rmsg; while (true)
while (true) { {
rmsg = i; if (count > 0) {
send (readrequest, rmsg); if (!empty (finished)) {
receive (mbox[i], rmsg); receive (finished, msg);
READUNIT (); count++;
rmsg = i; }
send (finished, rmsg); else if (!empty (writerequest)) {
} receive (writerequest, msg);
} writer_id = msg.id;
void writer(int j) count = count – 100;
{ }
message rmsg; else if (!empty (readrequest)) {
while(true) { receive (readrequest, msg);
rmsg = j; count--;
send (writerequest, rmsg); send (msg.id, "OK");
receive (mbox[j], rmsg); }
WRITEUNIT (); }
rmsg = j; if (count == 0) {
send (finished, rmsg); send (writer_id, "OK");
} receive (finished, msg);
} count = 100;
}
while (count < 0) {
receive (finished, msg);
count++;
}
}
}
Figure 5.24