Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python threading. How do I lock a thread?

I'm trying to understand the basics of threading and concurrency. I want a simple case where two threads repeatedly try to access one shared resource.

The code:

import threading  class Thread(threading.Thread):     def __init__(self, t, *args):         threading.Thread.__init__(self, target=t, args=args)         self.start() count = 0 lock = threading.Lock()  def increment():     global count      lock.acquire()     try:         count += 1         finally:         lock.release()     def bye():     while True:         increment()          def hello_there():     while True:         increment()  def main():         hello = Thread(hello_there)     goodbye = Thread(bye)          while True:         print count  if __name__ == '__main__':     main() 

So, I have two threads, both trying to increment the counter. I thought that if thread 'A' called increment(), the lock would be established, preventing 'B' from accessing until 'A' has released.

Running the makes it clear that this is not the case. You get all of the random data race-ish increments.

How exactly is the lock object used?

Additionally, I've tried putting the locks inside of the thread functions, but still no luck.

like image 708
Zack Avatar asked May 09 '12 22:05

Zack


People also ask

How do you stop a thread from threading in Python?

Using a hidden function _stop() : In order to kill a thread, we use hidden function _stop() this function is not documented but might disappear in the next version of python.

How do you implement locks in Python?

To loop through a set of code a specified number of times, we can use the range() function, The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and ends at a specified number.


1 Answers

You can see that your locks are pretty much working as you are using them, if you slow down the process and make them block a bit more. You had the right idea, where you surround critical pieces of code with the lock. Here is a small adjustment to your example to show you how each waits on the other to release the lock.

import threading import time import inspect  class Thread(threading.Thread):     def __init__(self, t, *args):         threading.Thread.__init__(self, target=t, args=args)         self.start()  count = 0 lock = threading.Lock()  def incre():     global count     caller = inspect.getouterframes(inspect.currentframe())[1][3]     print "Inside %s()" % caller     print "Acquiring lock"     with lock:         print "Lock Acquired"         count += 1           time.sleep(2)    def bye():     while count < 5:         incre()  def hello_there():     while count < 5:         incre()  def main():         hello = Thread(hello_there)     goodbye = Thread(bye)   if __name__ == '__main__':     main() 

Sample output:

... Inside hello_there() Acquiring lock Lock Acquired Inside bye() Acquiring lock Lock Acquired ... 
like image 170
jdi Avatar answered Oct 06 '22 05:10

jdi