• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

举例讲解Python编程中对线程锁的使用

python 搞代码 4年前 (2022-01-07) 36次浏览 已收录 0个评论

Python的threading模块中提供了多种锁的相关方法,Python的多线程不能同时执行,因而锁的使用非常关键,下面我们就来举例讲解Python编程中对线程锁的使用:

python的内置数据结构比如列表和字典等是线程安全的,但是简单数据类型比如整数和浮点数则不是线程安全的,要这些简单数据类型的通过操作,就需要使用锁。

 #!/usr/bin/env python3 # coding=utf-8 import threading shared_resource_with_lock = 0 shared_resource_with_no_lock = 0 COUNT = 100000 shared_resource_lock = threading.Lock() ####LOCK MANAGEMENT## def increment_with_lock(): global shared_resource_with_lock for i in range(COUNT): shared_resource_lock.acquire() shared_resource_with_lock += 1 shared_resource_lock.release() def decrement_with_lock(): global shared_resource_with_lock for i in range(COUNT): shared_resource_lock.acquire() shared_resource_with_lock -= 1 shared_resource_lock.release() ####NO LOCK MANAGEMENT ## def increment_without_lock(): global shared_resource_with_no_lock for i in range(COUNT): shared_resource_with_no_lock += 1 def decrement_without_lock(): global shared_resource_with_no_lock for i in range(COUNT): shared_resource_with_no_lock -= 1 ####the Main program if __name__ == "__main__": t1 = threading.Thread(target = increment_with_lock) t2 = threading.Thread(target = decrement_with_lock) t3 = threading.Thread(target = increment_without_lock) t4 = threading.Thread(target = decrement_without_lock) t1.start() t2.start() t3.start() t4.start() t1.join() t2.join() t3.join() t4.join() print ("the value of shared variable with lock management is %s"\ %shared_resource_with_lock) print ("the value of shared variable with race condition is %s"\ %shared_resource_with_no_lock) 

执行结果:

 $ ./threading_lock.py 
 the value of shared variable with lock management is 0 the value of shared variable with race condition is 0 

又如:

 import random import threading import time logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s) %(message)s', ) class Counter(object): def __init__(self, start=0): self.lock = threading.Lock() self.value = start def increment(self): logging.debug(time.ctime(time.time())) logging.debug('Waiting for lock') self.lock.acquire() try: pause = random.randint(1,3) logging.debug(time.ctime(time.time())) logging.debug('Acquired lock') self.value = self.value + 1 logging.debug('lock {0} seconds'.format(pause)) time.sleep(pause) finally: self.lock.release() def worker(c): for i in range(2): pause = random.randint(1,3) logging.debug(time.ctime(time.time())) logging.debug('Sleeping %0.02f', pause) time.sleep(pause) c.increment() logging.debug('Done') counter = Counter() for i in range(2): t = threading.Thread(target=worker, args=(counter,)) t.start() logging.debug('Waiting for worker threads') main_thread = threading.currentThread() for t in threading.enumerate(): if t is not main_thread: t.join() logging.debug('Counter: %d', counter.value) 

执行结果:

 $ python threading_lock.py 
 (Thread-1 ) Tue Sep 15 15:49:18 2015 (Thread-1 ) Sleeping 3.00 (Thread-2 ) Tue Sep 15 15:49:18 2015 (MainThread) Waiting for worker threads (Thread-2 ) Sleeping 2.00 (Thread-2 ) Tue Sep 15 15:49:20 2015 (Thread-2 ) Waiting for lock (Thread-2 ) Tue Sep 15 15:49:20 2015 (Thread-2 ) Acquired lock (Thread-2 ) lock 2 seconds (Thread-1 ) Tue Sep 15 15:49:21 2015 (Thread-1 ) Waiting for lock (Thread-2 ) Tue Sep 15 15:49:22 2015 (Thread-1 ) Tue Sep 15 15:49:22 2015 (Thread-2 ) Sleeping 2.00 (Thread-1 ) Acquired lock (Thread-1 ) lock 1 seconds (Thread-1 ) Tue Sep 15 15:49:23 2015 (Thread-1 ) Sleeping 2.00 (Thread-2 ) Tue Sep 15 15:49:24 2015 (Thread-2 ) Waiting for lock (Thread-2 ) Tue Sep 15 15:49:24 2015 (Thread-2 ) Acquired lock (Thread-2 ) lock 1 seconds (Thread-1 ) Tue Sep 15 15:49:25 2015 (Thread-1 ) Waiting for lock (Thread-1 ) Tue Sep 15 15:49:25 2015 (Thread-1 ) Acquired lock (Thread-1 ) lock 2 seconds (Thread-2 ) Done (Thread-1 ) Done (MainThread) Counter: 4 

acquire()中传入False值,可以检查是否获得了锁。比如:

 <div style="color:transparent">来源gaodai.ma#com搞##代!^码网</div>import logging import threading import time logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s) %(message)s', ) def lock_holder(lock): logging.debug('Starting') while True: lock.acquire() try: logging.debug('Holding') time.sleep(0.5) finally: logging.debug('Not holding') lock.release() time.sleep(0.5) return def worker(lock): logging.debug('Starting') num_tries = 0 num_acquires = 0 while num_acquires <3: time.sleep(0.5) logging.debug('trying to acquire') have_it=lock.acquire(0) try: num_tries +=1 if have_it: logging.debug('iteration %d: acquired', num_tries) num_acquires 1 else: not finally: lock.release() logging.debug('done after %d iterations', lock=threading.Lock() holder=threading.Thread(target=lock_holder, args=(lock,), name='LockHolder' ) holder.setdaemon(true) holder.start() worker=threading.Thread(target=worker, worker.start() <pre></div><p>执行结果:</p><div class="gaodaimacode"><pre class="prettyprint linenums"> $ python threading_lock_noblock.py 
 (LockHolder) Starting (LockHolder) Holding (Worker  ) Starting (LockHolder) Not holding (Worker  ) Trying to acquire (Worker  ) Iteration 1: Acquired (LockHolder) Holding (Worker  ) Trying to acquire (Worker  ) Iteration 2: Not acquired (LockHolder) Not holding (Worker  ) Trying to acquire (Worker  ) Iteration 3: Acquired (LockHolder) Holding (Worker  ) Trying to acquire (Worker  ) Iteration 4: Not acquired (LockHolder) Not holding (Worker  ) Trying to acquire (Worker  ) Iteration 5: Acquired (Worker  ) Done after 5 iterations 

线程安全锁

 threading.RLock() 

返回可重入锁对象。重入锁必须由获得它的线程释放。一旦线程获得了重入锁,同一线程可不阻塞地再次获得,获取之后必须释放。

通常一个线程只能获取一次锁:

 import threading lock = threading.Lock() print 'First try :', lock.acquire() print 'Second try:', lock.acquire(0) 

执行结果:

 $ python threading_lock_reacquire.py 
 First try : True Second try: False 

使用RLock可以获取多次锁:

 import threading lock = threading.RLock() print 'First try :', lock.acquire() print 'Second try:', lock.acquire(0) 

执行结果:

 python threading_rlock.py 
 First try : True Second try: 1 

再来看一个例子:

 #!/usr/bin/env python3 # coding=utf-8 import threading import time class Box(object): lock = threading.RLock() def __init__(self): self.total_items = 0 def execute(self,n): Box.lock.acquire() self.total_items += n Box.lock.release() def add(self): Box.lock.acquire() self.execute(1) Box.lock.release() def remove(self): Box.lock.acquire() self.execute(-1) Box.lock.release() ## These two functions run n in separate ## threads and call the Box's methods def adder(box,items): while items > 0: print ("adding 1 item in the box\n") box.add() time.sleep(5) items -= 1 def remover(box,items): while items > 0: print ("removing 1 item in the box") box.remove() time.sleep(5) items -= 1 ## the main program build some ## threads and make sure it works if __name__ == "__main__": items = 5 print ("putting %s items in the box " % items) box = Box() t1 = threading.Thread(target=adder,args=(box,items)) t2 = threading.Thread(target=remover,args=(box,items)) t1.start() t2.start() t1.join() t2.join() print ("%s items still remain in the box " % box.total_items) 

执行结果:

 $ python3 threading_rlock2.py 
 putting 5 items in the box adding 1 item in the box removing 1 item in the box adding 1 item in the box removing 1 item in the box adding 1 item in the box removing 1 item in the box removing 1 item in the box adding 1 item in the box removing 1 item in the box adding 1 item in the box 0 items still remain in the box 

以上就是举例讲解Python编程中对线程锁的使用的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:举例讲解Python编程中对线程锁的使用

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址