Sunday, 20 December 2015

Python: threading locks

Locks are used to synchronize the operations in multi-threaded environment. ‘threading.Lock’ class provide methods to acquire and release the lock.

First, I am going to explain simple application without locks.

Thread1: Prints all even numbers from 1 to 10
Thread2: Prints all odd numbers from 1 to 10
Requirement: Print all even numbers followed by odd numbers.

MyThread.py
import threading
import time

class MyThread(threading.Thread):
 def run(self):
  name=threading.current_thread().getName()
  
  if(name=="even"):
   for i in range(2, 10, 2):
    time.sleep(0.5)
    print("Even Number :", i)
  else:
   for i in range(1, 10, 2):
    time.sleep(0.5)
    print("Odd Number :", i)
    
thread1 = MyThread(name="even")
thread2 = MyThread(name="odd")

thread1.start()
thread2.start()

$ python3 MyThread.py 
Even Number : 2
Odd Number : 1
Odd Number : 3
Even Number : 4
Odd Number : 5
Even Number : 6
Even Number : 8
Odd Number : 7
Odd Number : 9

As you observe the output, both even and odd numbers are printed in mixed, but we want them to be printed in different way (Even numbers followed by odd numbers).

One way is by using thread join method. Other is using locks. Following program write the same application using locks.


MyThread.py
import threading
import time

class MyThread(threading.Thread):
 def run(self):
  name=threading.current_thread().getName()
  
  global numberLock
  
  numberLock.acquire()
  try:
   if(name=="even"):
    for i in range(2, 10, 2):
     time.sleep(0.5)
     print("Even Number :", i)
   else:
    for i in range(1, 10, 2):
     time.sleep(0.5)
     print("Odd Number :", i)
  finally:
   numberLock.release()
  
global numberLock
numberLock = threading.Lock()
 
thread1 = MyThread(name="even")
thread2 = MyThread(name="odd")

thread1.start()
thread2.start()

$ python3 MyThread.py 
Even Number : 2
Even Number : 4
Even Number : 6
Even Number : 8
Odd Number : 1
Odd Number : 3
Odd Number : 5
Odd Number : 7
Odd Number : 9


‘acquire’ and ‘release’ methods are used to acquire and release locks. Once a thread acquires lock, no thread can able to execute the synchronized code, until thread release the lock.

acquire(blocking=True, timeout=-1)
'acquire' method is used to acquire a lock. Returns True if the lock is acquired successfully, False if not. If this method is invoked with the blocking argument set to True, block until the lock is unlocked, then set it to locked and return True. When invoked with the blocking argument set to False, do not block.

You can set the maximum timeout by setting timeout value. It is a floating-point number, specifies the maximum number of seconds that this thread can block.  A timeout argument of -1 specifies an unbounded wait.

release()
Release a lock. This can be called from any thread, not only the thread which has acquired the lock. If you call this method on an unlocked lock, a RuntimeError is raised.





Previous                                                 Next                                                 Home

No comments:

Post a Comment