举例讲解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 过年祝福语简短祝妈妈
17 祝女儿简短祝福语大全
18 恩师诗词祝福语简短大全