举例讲解Python编程中对线程锁的使用
锁
python的内置数据结构比如列表和字典等是线程安全的,但是简单数据类型比如整数和浮点数则不是线程安全的,要这些简单数据类型的通过操作,就需要使用锁。
#!/usr/bin/envpython3
#coding=utf-8
importthreading
shared_resource_with_lock=0
shared_resource_with_no_lock=0
COUNT=100000
shared_resource_lock=threading.Lock()
####LOCKMANAGEMENT##
defincrement_with_lock():
globalshared_resource_with_lock
foriinrange(COUNT):
shared_resource_lock.acquire()
shared_resource_with_lock+=1
shared_resource_lock.release()
defdecrement_with_lock():
globalshared_resource_with_lock
foriinrange(COUNT):
shared_resource_lock.acquire()
shared_resource_with_lock-=1
shared_resource_lock.release()
####NOLOCKMANAGEMENT##
defincrement_without_lock():
globalshared_resource_with_no_lock
foriinrange(COUNT):
shared_resource_with_no_lock+=1
defdecrement_without_lock():
globalshared_resource_with_no_lock
foriinrange(COUNT):
shared_resource_with_no_lock-=1
####theMainprogram
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("thevalueofsharedvariablewithlockmanagementis%s"\
%shared_resource_with_lock)
print("thevalueofsharedvariablewithraceconditionis%s"\
%shared_resource_with_no_lock)
执行结果:
$./threading_lock.py
thevalueofsharedvariablewithlockmanagementis0 thevalueofsharedvariablewithraceconditionis0
又如:
importrandom
importthreading
importtime
logging.basicConfig(level=logging.DEBUG,
format='(%(threadName)-10s)%(message)s',
)
classCounter(object):
def__init__(self,start=0):
self.lock=threading.Lock()
self.value=start
defincrement(self):
logging.debug(time.ctime(time.time()))
logging.debug('Waitingforlock')
self.lock.acquire()
try:
pause=random.randint(1,3)
logging.debug(time.ctime(time.time()))
logging.debug('Acquiredlock')
self.value=self.value+1
logging.debug('lock{0}seconds'.format(pause))
time.sleep(pause)
finally:
self.lock.release()
defworker(c):
foriinrange(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()
foriinrange(2):
t=threading.Thread(target=worker,args=(counter,))
t.start()
logging.debug('Waitingforworkerthreads')
main_thread=threading.currentThread()
fortinthreading.enumerate():
iftisnotmain_thread:
t.join()
logging.debug('Counter:%d',counter.value)
执行结果:
$pythonthreading_lock.py
(Thread-1)TueSep1515:49:182015 (Thread-1)Sleeping3.00 (Thread-2)TueSep1515:49:182015 (MainThread)Waitingforworkerthreads (Thread-2)Sleeping2.00 (Thread-2)TueSep1515:49:202015 (Thread-2)Waitingforlock (Thread-2)TueSep1515:49:202015 (Thread-2)Acquiredlock (Thread-2)lock2seconds (Thread-1)TueSep1515:49:212015 (Thread-1)Waitingforlock (Thread-2)TueSep1515:49:222015 (Thread-1)TueSep1515:49:222015 (Thread-2)Sleeping2.00 (Thread-1)Acquiredlock (Thread-1)lock1seconds (Thread-1)TueSep1515:49:232015 (Thread-1)Sleeping2.00 (Thread-2)TueSep1515:49:242015 (Thread-2)Waitingforlock (Thread-2)TueSep1515:49:242015 (Thread-2)Acquiredlock (Thread-2)lock1seconds (Thread-1)TueSep1515:49:252015 (Thread-1)Waitingforlock (Thread-1)TueSep1515:49:252015 (Thread-1)Acquiredlock (Thread-1)lock2seconds (Thread-2)Done (Thread-1)Done (MainThread)Counter:4
acquire()中传入False值,可以检查是否获得了锁。比如:
importlogging
importthreading
importtime
logging.basicConfig(level=logging.DEBUG,
format='(%(threadName)-10s)%(message)s',
)
deflock_holder(lock):
logging.debug('Starting')
whileTrue:
lock.acquire()
try:
logging.debug('Holding')
time.sleep(0.5)
finally:
logging.debug('Notholding')
lock.release()
time.sleep(0.5)
return
defworker(lock):
logging.debug('Starting')
num_tries=0
num_acquires=0
whilenum_acquires<3:
time.sleep(0.5)
logging.debug('Tryingtoacquire')
have_it=lock.acquire(0)
try:
num_tries+=1
ifhave_it:
logging.debug('Iteration%d:Acquired',
num_tries)
num_acquires+=1
else:
logging.debug('Iteration%d:Notacquired',
num_tries)
finally:
ifhave_it:
lock.release()
logging.debug('Doneafter%diterations',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()
执行结果:
$pythonthreading_lock_noblock.py
(LockHolder)Starting (LockHolder)Holding (Worker)Starting (LockHolder)Notholding (Worker)Tryingtoacquire (Worker)Iteration1:Acquired (LockHolder)Holding (Worker)Tryingtoacquire (Worker)Iteration2:Notacquired (LockHolder)Notholding (Worker)Tryingtoacquire (Worker)Iteration3:Acquired (LockHolder)Holding (Worker)Tryingtoacquire (Worker)Iteration4:Notacquired (LockHolder)Notholding (Worker)Tryingtoacquire (Worker)Iteration5:Acquired (Worker)Doneafter5iterations
线程安全锁
threading.RLock()
返回可重入锁对象。重入锁必须由获得它的线程释放。一旦线程获得了重入锁,同一线程可不阻塞地再次获得,获取之后必须释放。
通常一个线程只能获取一次锁:
importthreading lock=threading.Lock() print'Firsttry:',lock.acquire() print'Secondtry:',lock.acquire(0)
执行结果:
$pythonthreading_lock_reacquire.py
Firsttry:True Secondtry:False
使用RLock可以获取多次锁:
importthreading lock=threading.RLock() print'Firsttry:',lock.acquire() print'Secondtry:',lock.acquire(0)
执行结果:
pythonthreading_rlock.py
Firsttry:True Secondtry:1
再来看一个例子:
#!/usr/bin/envpython3
#coding=utf-8
importthreading
importtime
classBox(object):
lock=threading.RLock()
def__init__(self):
self.total_items=0
defexecute(self,n):
Box.lock.acquire()
self.total_items+=n
Box.lock.release()
defadd(self):
Box.lock.acquire()
self.execute(1)
Box.lock.release()
defremove(self):
Box.lock.acquire()
self.execute(-1)
Box.lock.release()
##Thesetwofunctionsrunninseparate
##threadsandcalltheBox'smethods
defadder(box,items):
whileitems>0:
print("adding1iteminthebox\n")
box.add()
time.sleep(5)
items-=1
defremover(box,items):
whileitems>0:
print("removing1iteminthebox")
box.remove()
time.sleep(5)
items-=1
##themainprogrambuildsome
##threadsandmakesureitworks
if__name__=="__main__":
items=5
print("putting%sitemsinthebox"%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("%sitemsstillremaininthebox"%box.total_items)
执行结果:
$python3threading_rlock2.py
putting5itemsinthebox adding1iteminthebox removing1iteminthebox adding1iteminthebox removing1iteminthebox adding1iteminthebox removing1iteminthebox removing1iteminthebox adding1iteminthebox removing1iteminthebox adding1iteminthebox 0itemsstillremaininthebox
热门推荐
10 新婚宴祝福语简短大全
11 客户新房祝福语简短大气
12 访贫问苦祝福语简短句子
13 生日祝福语陌生女生简短
14 女儿出阁的祝福语简短
15 考进高中祝福语简短
16 上班祝福语简短10字
17 生日祝福语男生韩语简短
18 婚礼伴娘祝福语大全简短