举例讲解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 出阁宴祝福语姐姐简短