L02 Processes Threads
L02 Processes Threads
Synchronization
Lecture 02
Program Parallelization: Steps
Done by programmer
3 main steps: Sequential
Algorithm
1. Decomposition of the decompose
computations
Tasks
2. Scheduling (assignment of schedule
tasks to processes (or
threads)) Processes
or Threads
map
3. Mapping of processes (or
threads) to physical processors Physical Cores
(or cores) & Processors
[ CS3210 - AY2425S1 - L02 ]
2
Program Parallelization: Steps
3 main steps: Sequential
Algorithm
1. Decomposition of the decompose
computations
Tasks
2. Scheduling (assignment of
Done by OS &schedule
libraries*
tasks to processes (or
threads)) Processes
or Threads
map
3. Mapping of processes (or
threads) to physical Physical Cores
processors (or cores) & Processors
[ CS3210 - AY2425S1 - L02 ]
3
Abstractions of flow of control
Data
(for global variables)
The entire
memory Heap
space (for dynamic allocation)
Stack
(for function invocations)
2 types of execution:
Time slicing execution – pseudo-parallelism
Parallel execution of processes on different resources
}}
Synchronous Asynchronous
Occur due to program execution Occur independently of program
Have to execute an exception execution
handler Have to execute an interrupt
handler
Taken from Operating System Concepts (7th Edition) by Silberschatz, Galvin & Gagne, published by Wiley
2 types of threads
User-level threads
Kernel threads
Disadvantages
OS cannot map different threads of the same process to different
execution resources no parallelism
OS cannot switch to another thread if one thread executes a blocking
I/O operation
Thread library is
responsible for the
scheduling of user-level
threads
Possible problems?
Producer Consumer
event = waitForEvent () items.wait ()
mutex.wait () mutex.wait ()
buffer.add ( event ) event = buffer.get ()
items.signal () mutex.signal ()
mutex.signal () event.process ()
Producer Consumer
event = waitForEvent () items.wait ()
mutex.wait () mutex.wait ()
buffer.add ( event ) event = buffer.get ()
mutex.signal () mutex.signal ()
items.signal () event.process ()
Producer Consumer
event = waitForEvent () items.wait ()
mutex.wait () mutex.wait ()
buffer.add ( event ) event = buffer.get ()
mutex.signal () mutex.signal ()
items.signal () event.process ()
Producer Consumer
event = waitForEvent () mutex.wait ()
mutex.wait () items.wait ()
buffer.add ( event ) event = buffer.get ()
mutex.signal () mutex.signal ()
items.signal () event.process ()
Producer Consumer
event = waitForEvent () items.wait ()
spaces.wait () mutex.wait ()
Writers Readers
roomEmpty.wait () mutex.wait ()
#critical section for writers readers += 1
if readers == 1:
roomEmpty.signal () roomEmpty.wait () # first in locks
mutex.signal ()
# critical section for readers
mutex.wait ()
readers -= 1
if readers == 0:
roomEmpty.signal () # last out unlocks
mutex.signal ()
Writers Readers
roomEmpty.wait () readLightswitch.lock (roomEmpty )
#critical section for writers # critical section
roomEmpty.signal () readLightswitch.unlock (roomEmpty)
#starving writers
Use a
turnstile = Semaphore (1)
Writers Readers
turnstile.wait () turnstile.wait ()
roomEmpty.wait () turnstile.signal ()
# critical section for writers
readSwitch.lock ( roomEmpty )
Writers Readers
writeSwitch.lock (noReaders) noReaders.wait ()
noWriters.wait () readSwitch.lock (noWriters)
# critical section for writers noReaders.signal ()
noWriters.signal()
# critical section for readers
writeSwitch.unlock (noReaders) readSwitch.unlock ( noWriters )