视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
举例Python编程中对线程锁
2020-11-27 14:26:22 责编:小采
文档

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值,可以检查是否获得了锁。比如:

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:
 logging.debug('Iteration %d: Not acquired',
 num_tries)
 finally:
 if have_it:
 lock.release()
 logging.debug('Done after %d iterations', num_tries)
lock = threading.Lock()
holder = threading.Thread(target=lock_holder,
 args=(lock,),
 name='LockHolder')
holder.setDaemon(True)
holder.start()
worker = threading.Thread(target=worker,
 args=(lock,),
 name='Worker')
worker.start()

执行结果:

$ 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
")
 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编程中对线程锁相关文章请关注PHP中文网!

下载本文
显示全文
专题