共享變量
當多個線程同時訪問一個變量的時候,會產生共享變量的問題。
問題解決:鎖(是一個標誌,表示一個線程正在佔用一些資源),信號燈
鎖的使用方法:上鎖,使用共享資源,放心的用,取消鎖,釋放鎖。
案例1
import threading
sum=0
loopsum=1000000
lock=threading.Lock()
def myAdd():
global sum,loopsum
for i in range(1,loopsum):
#上鎖,申請鎖
lock.acquire()
sum+=1
#釋放鎖
lock.release()
def myMinu():
global sum, loopsum
for i in range(1,loopsum):
#上鎖,申請鎖
lock.acquire()
sum-=1
#釋放鎖
lock.release()
if __name__=='__main__':
print('staring.....{0}'.format(sum))
t1=threading.Thread(target=myAdd,args=())
t2=threading.Thread(target=myMinu,args=())
t1.start()
t2.start()
t1.join()
t2.join()
print('done....{0}'.format(sum))
線程安全問題
如果一個資源/變量,他對於多線程來講,不用枷鎖也不會引起任何問題,則稱爲線程安全。
生產者消費者問題(模型)
可以用來待見消息隊列
案例2
import threading
import time
#from queue import Queue
import queue
class Producer(threading.Thread):
def run(self):
global queue
count=0
while True:
if queue.qsize()<1000:
for i in range(100):
count=count+1
msg='生成產品'+str(count)
queue.put(msg)
print(msg)
time.sleep(0.5)
class Consumer(threading.Thread):
def run(self):
global queue
while True:
if queue.qsize() >100:
for i in range(3):
msg = self.name+'消費了' +queue.get()
print(msg)
time.sleep(0.5)
if __name__=='__main__':
queue=queue.Queue()
for i in range(500):
queue.put('初始產品'+str(i))
for i in range(2):
p=Producer()
p.start()
for i in range(5):
c=Consumer()
c.start()
semphore
允許一個資源最多由幾個線程同時使用
案例3
import threading
import time
#參數定義最多幾個線程同時使用資源
semaphore=threading.Semaphore(3)
def func():
if semaphore.acquire():
for i in range(5):
print(threading.currentThread().getName()+'get semaphore')
time.sleep(15)
semaphore.release()
print(threading.currentThread().getName()+'release semaphore')
for i in range(8):
t1=threading.Thread(target=func)
t1.start()
Timer
使用方法在一個指定的秒數之後調用方法-threading.Timer(sec,func)
可重入鎖
一個鎖可以被一個線程多次申請
主要解決遞歸調用的時候,需要申請鎖的情況
mutex=threading.RLock()