Professional Documents
Culture Documents
Unit 4. Chapter 2 Threads: Thread Synchronization
Unit 4. Chapter 2 Threads: Thread Synchronization
CHAPTER 2 THREADS
Study material for programs explained in video files named as
race_condition,race_condition1 and thread_synchr
Thread Synchronization:
To understand the race condition let us consider one more example. Suppose two railway
reservation clerks from two different places send request for reserving a same seat at the same
time to the server. Two client request are handled by two threads, as two threads act
simultaneously on function that do the reservation, we may get a wrong result such as same seat
is reserved for two person. This is race condition this occurs because two or more thread act on
same function at the same time. To avoid race condition synchronization of thread is needed.
Mean at a time only one thread should act on a method or function.
class Railway:
def __init__(self,seats):
self.seats_av=seats
def reserve(self,w):
if self.seats_av>=w:
name=current_thread().getName()
self.seats_av-=w
sleep(1)
else:
r=Railway(1)
t1=Thread(target=r.reserve,args=(1,))
t2=Thread(target=r.reserve,args=(1,))
t1.setName("First Person")
t2.setName("Second Person")
t1.start()
t2.start()
output1:
no of seats avialbel 1
no of seats avialbel 0
Output2:
In the above program race condition is occurred. To avoid a race condition threads must be
synchronized. Thread synchronization means when a thread is already acting on object,
preventing any other thread from acting on the same object. Thread synchronization is done
using the following techniques
Using locks
Using semaphores
Locks can be used to lock the object on which the thread is acting. When a thread enters the
object it locks the object and after the execution is completed, it will unlock the object and comes
out of it.
We can create a lock by creating a object of Lock class as
l=Lock()
l.acquire()
l.release()
class Railway:
def __init__(self,seats):
self.seats_av=seats
self.l=Lock()
def reserve(self,w):
self.l.acquire()
if self.seats_av>=w:
name=current_thread().getName()
self.seats_av-=w
sleep(1)
else:
print("Sorry no seats are avialble")
self.l.release()
r=Railway(1)
t1=Thread(target=r.reserve,args=(1,))
t2=Thread(target=r.reserve,args=(1,))
t1.setName("First Person")
t2.setName("Second Person")
t1.start()
t2.start()
output1:
no of seats avialbel 1
no of seats avialbel 0
Output2:
no of seats avialbel 1
no of seats avialbel 0
For every execution of the program we will get the same output
if the counter value is not given, the default value of the counter will be 1. When acquire()
method is called, the counter gets decremented by 1 and when release() is called it is
incremented by 1. These methods are used in the following format:
class Railway:
def __init__(self,seats):
self.seats_av=seats
self.l=Semaphore()
def reserve(self,w):
self.l.acquire()
if self.seats_av>=w:
name=current_thread().getName()
self.seats_av-=w
sleep(1)
else:
print("Sorry no seats are avialble")
self.l.release()
r=Railway(1)
t1=Thread(target=r.reserve,args=(1,))
t2=Thread(target=r.reserve,args=(1,))
t1.setName("First Person")
t2.setName("Second Person")
t1.start()
t2.start()
output1:
no of seats avialbel 1
no of seats avialbel 0
Output2:
no of seats avialbel 1
no of seats avialbel 0