一、鎖在多線程中的使用:線程互斥
lock = threading.Lock()#創建一個鎖對象
1、with lock:
pass
和進程使用的方式相同
2、控制線程結束的時間
通過一個全局變量
# encoding=utf-8
import threading,time,Queue,random
exitFlag = False
def write(lock,queue):
while exitFlag != True:
with lock:
data = random.randint(1,100)
print 'put:',data
queue.put(data)
time.sleep(1)
def read(queue):
while exitFlag != True:
print 'get:',queue.get()
time.sleep(1)
if __name__ == '__main__':
lock = threading.Lock()
queue = Queue.Queue()
t1 = threading.Thread(target=write,args=(lock,queue))
t2 = threading.Thread(target=write,args=(lock,queue))
t3 = threading.Thread(target=read,args=(queue,))
t1.start()
t2.start()
t3.start()
time.sleep(10)
exitFlag = True
t1.join()
t2.join()
t3.join()
二、線程同步
1、生產者--消費者模式
Queue() 作為生產者和消費者的中介
from
class Producer(threading.Thread):
def __init__(self,t_name,queue):
threading.Thread.__init__(self,name=t_name)#繼承父類的構造方法的目的:初始化一些線程實例,
self.data=queue
def run(self):
for i in xrange(5):
print '%s:%s is producing %d to the queue\n'%(time.ctime(),self.getname(),i)
self.data.put(i)
time.sleep(2)
print '%s:%s put finished \n'%(time.ctime(),self.getname(),i)
def Consumer(threading.Thread):
def __init__(self,t_name,queue):
threading.Thread.__init__(self,name=t_name)
self.data=queue
def run(self):
for i in xrange(5):
val=self.data.get()
print '%s:%s is consumer %d in the queue\n'%(time.ctime(),self.getname(),val)
print '%s:%s consumer finished \n'%(time.ctime(),self.getname(),i)
if __name=='__main__':
queue=Queue()#沒有制定隊列大小,默認為無限大,可以不受限制的放入隊列
producer=Producer('Pro',queue)
consumer=Consumer('Con',queue)
producer.start()
time.sleep(1)
consumer.start()
producer.join()
consumer.join()
print 'mainThread end'
2、Event 信號傳遞
event=threading.Event()
import threading,time,Queue,random
def write(lock,queue,event):
while not event.isSet():
with lock:
thread = threading.currentThread()
data = random.randint(1,100)
print 'this is thread:',thread.getName(),'put:',data
queue.put(data)
time.sleep(1)
def read(queue):
while not event.isSet():
print 'get:',queue.get()
time.sleep(1)
if __name__ == '__main__':
lock = threading.Lock()
queue = Queue.Queue()
event=threading.Event()
t1 = threading.Thread(target=write,args=(lock,queue,event))
t2 = threading.Thread(target=write,args=(lock,queue,event))
t3 = threading.Thread(target=read,args=(queue,))
t1.start()
t2.start()
t3.start()
time.sleep(10)
event.set()
t1.join()
t2.join()
t3.join()
3、lock :只能加一把鎖
4、semaphore:可以加多把鎖
設置限制最多3個線程同時訪問共享資源:s = threading.Semaphore(3)
5、event:線程等待某一時間的發生,之后執行邏輯
6、Condition 條件
con=threading.Condition()
使用場景:處理復雜的邏輯。基於鎖來實現的
兩個線程之間做一些精准的通信
線程A做了某一件事,中途需要停止
線程B做另外一件事情,線程B通知線程A
線程A繼續
(1)額外提供了wait()方法和notify()方法,用於處理復雜的邏輯
(2)wait()釋放鎖,並且等待通知
(3)Notify()喚醒對方,可以繼續下去。但是需要兩個線程之間需要搶鎖,誰搶到執行誰
通過(2)和(3),實現線程間的通信。
import threading
import time
product = 0
exitFlag = False
def consumer(con):
global product
while exitFlag != True:
with con:
print 'enter consummer thread'
if product == 0:
con.wait()
else:
print 'now consummer 1 product'
product -= 1
print 'after consummer, we have ',product,'product now'
time.sleep(2)
def producer(con):
global product
while exitFlag != True:
with con:
print 'enter producer thread'
product += 1
con.notify()
print 'after producer, we have ', product, 'product now'
time.sleep(2)
if __name__ == '__main__':
con = threading.Condition()
c1 = threading.Thread(target=consumer,args=(con,))
p1 = threading.Thread(target=producer, args=(con,))
c1.start()
p1.start()
time.sleep(6)
exitFlag = True
c1.join()
p1.join()
7、死鎖
t1:擁有lock1鎖,申請lock2鎖
t2:擁有lock2鎖,申請lock1鎖
(1)如何盡量的保證不出現死鎖:
定義鎖的使用順序