2. SESSION OUTCOMES
⢠After this session, students will be able to:
⢠Explain the concept of Race Condition
⢠Explain the concept of Critical Region
⢠Explain the concept of Mutual Exclusion
⢠Explain the solutions of Mutual Exclusion
⢠Explain the concept of Semaphore
⢠Explain the concept of Mutex
2
3. CONTENTS
⢠Race Condition
⢠Critical Regions
⢠Mutual Exclusion with BusyWaiting
⢠Sleep &Wakeup Concept
⢠Semaphore
⢠Mutexes
⢠Mutexes in Pthread
3
4. INTERPROCESS COMMUNICATION
⢠Processes frequently need to communicate with other processes.
⢠For example,
⢠the output of the first process must be passed to the second process, and so on down the
line.
⢠The three main issues:
⢠How one process can pass information to another.
⢠Making sure two or more processes do not get in each otherâs way
⢠Proper sequencing when dependencies are present
4
5. RACE CONDITION
⢠Race conditions are situations where two or more processes are reading or writing
some shared data and the final result depends on who runs precisely when.
⢠Shared data/storage may be in main memory (shared variable) or it may be a shared file
where
5
6. RACE CONDITION
⢠Example: Printer Spooler
⢠Supposed that we have
⢠2 processes, Process A & Process B, would like to print.
⢠In the memory, there is a printer spooler, which is special directory for storing a queue of files to
be printed.
⢠There is a background process, printer daemon. It periodically checks to see if there is any file to
be printed, if so, it prints and then removed that file from the printer spooler.
Print âabc.txtâ Print âxyz.txtâ
6
7. RACE CONDITION
⢠Example: Printer Spooler
⢠Supposed that we have (conât)
⢠The printer spooler has a very large number of slots, numbered 0, 1, 2, âŚ
⢠There are 2 shared variables: out & in.
⢠out â points to the next file to be printed.
⢠in â points to the next free slot in the directory.
⢠At some certain instance, slot 0 - 3 are empty. Slots 4 â 6 are full.
7
8. RACE CONDITION
⢠Example: Printer Spooler
⢠Supposed that we have (conât)
⢠Process A reads in and stores the value, 7, in a local variable called next_free_slot.
⢠Unfortunately, a clock interrupts and CPU decides that Process A has run long enough. CPU
switches to Process B.
⢠Process B also reads in and also gets a 7. It then stores 7 in its local variable next_free_slot.
8
10. RACE CONDITION
⢠Example: Printer Spooler
⢠Supposed that we have (conât)
⢠Process B stores the name of its file in slot 7 and updates in to be an 8. It then goes off and does
other things.
⢠Finally, CPU allows Process A to run again! Process A starts from the place where it left off. It
looks at next_free_slot, finds 7 there, and writes its file name in slot 7, overwriting the file name of
Process B!!!
⢠Process A then computes next_free_slot += 1, which is 8, and set in to 8.
⢠The printer cannot detect anything and prints the file of Process A.
⢠The user of Process B waits for the file at the printer forever !!! Why so long?
10
12. CRITICAL REGIONS
⢠Since race conditions cause a serious problem, we would like to avoid them.
⢠We can avoid by using the mutual exclusion.
⢠Mutual exclusion is a way of making sure that if one process is using a shared variable
or file, the other processes will be excluded from doing the same thing.
⢠A critical region (or critical section) is the part of the program where the shared
memory is accessed.
12
13. CRITICAL REGIONS
⢠We need to maintain 4 conditions about a critical region:
I. No two processes may be simultaneously inside their critical regions.
II. No assumption may be made about speeds or the number of CPUs.
III. No process running outside its critical region may be block any process.
IV. No process should have to wait forever to enter its critical region.
13
16. MUTUAL EXCLUSION WITH BUSY WAITING
⢠There are several solutions for mutual exclusion issue:
⢠Disabling Interrupts
⢠LockVariables
⢠Strict Alternation
⢠Petersonâs Solution
⢠TSL
16
17. DISABLING INTERRUPTS
⢠This approach allows each process to disable all interrupts just after entering its critical
region and re-enable them just before leaving it.
⢠When the interrupt is disabled, a clock cannot interrupt.The scheduler then wonât switch a
process.
⢠Drawback:
⢠It is not a good idea to allow user processes to have an ability to disable interrupts.
⢠The system can be crashed if every process has disabled interrupts forever.
⢠It is a useful technique within OS but it is not appropriate as a general mutual exclusion
mechanism for user processes.
17
18. LOCKVARIABLES
⢠This approach introduces a single, shared (lock) variable, initially 0.
⢠When a process wants to enter its critical region, it first tests the lock
⢠If the lock is 0, the process sets it to 1 and enters the critical region.
⢠If the lock is 1, the process waits until it becomes 0.
⢠However, this approach cannot solve the race condition.The situation similar to printer
spooling issue can occur anyway.
18
19. STRICT ALTERNATION
⢠A programmer can impose the strict alternation inside the program code by writing a
condition for each process to test whether the turn belongs to it.
⢠If so, the process enters the critical region and change the turn right after exiting.
⢠If not, the process waits (busy waiting) until the turn belongs to it.
19
20. A proposed solution to the critical-region problem.
(a) Process 0.
(b) Process 1.
In both cases, be sure to note that the semicolons terminating the while statements.
20
21. STRICT ALTERNATION
⢠Continuously testing a variable (turn) until some value appears is called busy waiting.
⢠We should avoid busy waiting because it wastes CPU time.
⢠A lock that uses busy waiting is called a spin lock.
⢠However, strict alternation is not good because it can violate condition 3 (condition 3
state that âNo process running outside its critical region may be block any processâ).
⢠Give a scenario that the strict alternation violates condition 3?
⢠Solution: See page 124, paragraphs 1 â 3.
21
22. PETERSONâS SOLUTION
⢠Petersonâs Solution preserves all three conditions:
⢠Mutual Exclusion is assured as only one process can access the critical section at any time.
⢠Progress is also assured, as a process outside the critical section does not blocks other
processes from entering the critical section.
⢠BoundedWaiting is preserved as every process gets a fair chance.
22
25. PETERSONâS SOLUTION
⢠Before using shared variables, each process calls enter_region with its own process
number, 0 or 1, as parameter.
⢠This call causes it to wait, if need be, until it is safe to enter.
⢠After it has finished, the process calls leave_region to indicate that it is done.
⢠With Petersonâs algorithm, what will happen when two processes call enter_region
almost simultaneously?
⢠Solution: See page 125, the last paragraph.
25
27. TSL (TEST AND SET LOCK)
⢠This approach requires a little help from the hardware.
⢠Some computers have a Test and Set Lock instruction like:
⢠It reads the contents of the memory LOCK into register RX and then stores a non-zero
value at the memory address LOCK.
⢠The operation to read and store is indivisible.
⢠CPU executingTSL locks the memory bus to prohibit other CPUs from accessing
memory.
TSL RX, LOCK
27
28. TSL (TEST AND SET LOCK)
⢠LOCK, which is a shared variable, is used to coordinate access to shared memory.
⢠When LOCK is 0, any process may set it to 1 and then read or write the shared memory.
⢠When it is done, the process sets LOCK back to 0.
28
30. TSL (TEST AND SET LOCK)
⢠Before entering its critical region, a process calls enter_region, which does busy waiting
until the lock is free; then it acquires the lock and returns.
⢠After leaving the critical region, the process calls leave_region, which stores a 0 in LOCK.
⢠An alternative ofTSL is XCHG, which exchanges the contents of two locations
atomically.
30
31. SLEEP & WAKEUP CONCEPT
⢠We have learned multiple approaches to deal with mutual exclusion.
⢠However, we still cannot eliminate busy waiting from the algorithm.
⢠Busy waiting wastes CPU time and causes priority inversion problem.
⢠A priority inversion problem is the situation that some low priority process has
never got a chance to leave its critical region.
31
32. SLEEP & WAKEUP CONCEPT
⢠There are approaches that block instead of wasting CPU time.
⢠One approach is pair sleep and wakeup.
⢠Sleep is a system call that causes the caller to block until another process wakes it up.
⢠Wakeup call has 1 parameter, the process to be awakened.
32
33. SLEEP & WAKEUP CONCEPT
⢠The producer-consumer problem
⢠This problem shows how to implement sleep and wakeup.
⢠We have 2 processes, producer and consumer, share a common, fixed-size buffer.
⢠The producer puts information into the buffer.
⢠The consumer takes it out.
Buffer
Producer
Consumer
33
I will produce
until there is no
empty slot.
I will consume
until the buffer is
empty.
34. SLEEP & WAKEUP CONCEPT
⢠The producer-consumer problem (continue)
⢠Trouble arises when the producer wants to put a new item in the buffer, but it is already full.
⢠The solution is for the producer to go to sleep, to be awakened when the consumer has
removed one or more items from the buffer.
⢠Similarly, if the consumer wants to remove an item from the buffer and sees that the buffer is
empty, it goes to sleep until the producer puts something in the buffer and wakes it up.
⢠To keep track of the number of items in the buffer, we will need a variable count.
34
36. SLEEP & WAKEUP CONCEPT
⢠The producer-consumer problem (continue)
⢠However, the race condition can occur !!!
⢠Imagine that the buffer is empty and the consumer has just read count to see if it is 0.
⢠At that instant, the scheduler decides to stop running the consumer and start running the
producer.
⢠The producer inserts an item in the buffer, increments count, and wakes the consumer up.
⢠Unfortunately, the consumer is not yet logically asleep, so the wake up signal is lost.
36
37. SLEEP & WAKEUP CONCEPT
⢠The producer-consumer problem (continue)
⢠When the consumer takes the turn, it will test the value of count it previously read, find it to
be 0, and go to sleep.
⢠Sooner or later, the producer will fill up the buffer and also go to sleep. Both will sleep forever
!!!
⢠This problem can be solved by using wakeup waiting bit.
⢠When a wakeup is sent to a process that is still awake, this bit is set.
⢠Later, when the process tries to go to sleep, if the wakeup waiting bit is on, it will be turned
off, but the process will stay awake.
37
38. SEMAPHORE
⢠A semaphore is a variable that used to count the number of wakeups saved for future
used.
⢠Semaphore is signaling mechanism.
⢠A semaphore could have the value 0, indicating that no wakeups were saved.
⢠It could have some positive value if one or more wakeups were pending.
⢠A semaphore can have 2 operations: down (sleep) and up (wake).
38
40. SEMAPHORE
⢠The down operation checks to see if the value is greater than 0
⢠If so, it decrements the value and juts continues.
⢠Else, the process is put to sleep without completing the down for the moment.
⢠Checking the value, changing it, and possibly going to sleep, are all done as a single
indivisible atomic action.
⢠The up operation increments the value.
⢠A semaphore can be used to solve the producer-consumer problem.
40
41. SEMAPHORE
⢠There are two types of semaphores : Binary Semaphores and Counting
Semaphores
⢠Binary Semaphores :They can only be either 0 or 1.
⢠Counting Semaphores :
⢠They can have any value and are not restricted over a certain domain.
⢠They can be used to control access a resource that has a limitation on the number of simultaneous
accesses.
⢠The semaphore can be initialized to the number of instances of the resource.
41
42. SEMAPHORE
⢠Counting Semaphores : Example
⢠Whenever a process wants to use that resource, it checks if the number of remaining
instances is more than zero, i.e., the process has an instance available.
⢠Then, the process can enter its critical section thereby decreasing the value of the counting
semaphore by 1.
⢠After the process is over with the use of the instance of the resource, it can leave the critical
section thereby adding 1 to the number of available instances of the resource.
42
44. SEMAPHORE
⢠From the program, it used 3 semaphores.
⢠Full: for containing the number of slots that are full.
⢠Empty: for counting the number of slots that are empty.
⢠Mutex: to make sure the producer and consumer do not access the buffer at the same time
(binary semaphore).
44
45. MUTEXES
⢠Mutual Exclusion Object is shortly termed as Mutex.
⢠Mutex is locking mechanism.
⢠The mutex object allows the multiple program threads to use the same resource but one
at a time not simultaneously.
45
46. MUTEXES
⢠Mutex is a shared variable that can be in one of two states:
⢠unlocked or
⢠locked.
⢠Consequently, only 1 bit is required to represent it, but in practice an integer often is
used, with 0 meaning unlocked and all other values meaning locked.
46
47. MUTEXES PROCEDURES
⢠When a thread (or process) needs access to a critical region, it calls mutex_lock. If the
mutex is currently unlocked (meaning that the critical region is available), the call
succeeds and the calling thread is free to enter the critical region.
⢠On the other hand, if the mutex is already locked, the calling thread is blocked until the
thread in the critical region is finished and calls mutex_unlock.
47
49. KEY DIFFERENCES BETWEEN SEMAPHORE AND
MUTEX
49
Semaphore Mutex
Semaphore is a signalling mechanism as down()
and up() operation
Mutex is a locking mechanism
Semaphore is typically an integer variable Mutex is an object
Semaphore allows multiple program threads to
access the finite instance of resources.
Mutex allows multiple program threads to access
a single shared resource but one at a time.
Semaphore variable value can be modified
by any process that acquires or releases
resource by performing wait() and signal()
operation.
Lock acquired on the mutex object can be
released only by the process that has acquired
the lock on mutex object.
50. KEY DIFFERENCES BETWEEN SEMAPHORE AND
MUTEX
50
Semaphore Mutex
Semaphore are of two types counting
semaphore and binary semaphore
Binary semaphore which is quite similar to the
mutex
Semaphore variable value is modified
by down() and up() operation apart from
initialization.
The mutex object is locked or unlocked by the
process acquiring or releasing the resource.
If all the resources are acquired by the process,
and no resource is free then the process desiring
to acquire resource performs down() operation
on semaphore variable and blocks itself till the
count of semaphore become greater than 0.
A mutex object is already locked then the
process desiring to acquire resource waits and
get queued by the system till the resource is
released and mutex object gets unlocked.
51. MUTEXES IN PTHREADS
⢠Pthreads provides a number of functions that can be used to synchronize threads.
⢠The basic mechanism uses a mutex variable, which can be locked or unlocked, to guard
each critical region.
51
53. MUTEXES IN PTHREADS
⢠Pthreads offers a second synchronization mechanism: condition variables.
⢠Condition variables allow threads to block due to some condition not being met.
53
Some of the Pthreads calls relating to condition variables.