今天我們來介紹多線程。
進程裏有很多目標,多線程的目的簡言之就是加快進程,提高效率,多個操作同時進行。
下面來看代碼:
一.初識
import time
import threading
###############單線程##############################
def coding():
for x in range(3):
print("正在玩孫尚香%s"%x)
time.sleep(1)
def codis():
for x in range(3):
print("正在玩孫權%s" %x)
time.sleep(1)
def main():
coding()
codis()
if __name__ == '__main__':
main()
######3##############多線程###########################
def coding():
for x in range(3):
print("正在玩孫尚香%s" % threading.current_thread())#打印當前線程的名字
time.sleep(1)
def codis():
for x in range(3):
print("正在玩孫權%s" % threading.current_thread())#打印當前線程的名字
time.sleep(1)
def main():
t1=threading.Thread(target=coding)#創建線程
t2=threading.Thread(target=codis)#創建線程
t1.start()
t2.start()
print(threading.enumerate())#打印所有線程的名字
if __name__ == '__main__':
main()
#二.使用thread類創建多線程
#二.使用thread類創建多線程
class CodingThread(threading.Thread):
# def run(self):
# for x in range(3):
# print("正在玩孫尚香%s" % threading.current_thread()) # 打印當前線程的名字
time.sleep(1)
class DrawThread(threading.Thread):
def run(self):
for x in range(3):
print("正在玩孫權%s" % threading.current_thread())
time.sleep(1)
def main():
t1=CodingThread()
t2=DrawThread()
t1.start()
t2.start()
if __name__ == '__main__':
main()
三.多線程共享全局變量及鎖機制
VALUE=0
gLook=threading.Lock()#鎖機制1
def add_value():
global VALUE
gLook.acquire()#鎖機制2
for x in range(10000000):
VALUE+=1
gLook.release()#鎖機制3
print(VALUE)
def main():
for x in range(2):
t1=threading.Thread(target=add_value)
t1.start()
if __name__ == '__main__':
main()
四.多線程實例(生產者與消費者模式)
lock版本
import time
import threading
import random
gMoney=1000
gLock=threading.Lock()
gtotalTimes=10
gTime=0
class Producer(threading.Thread):
def run(self):
global gMoney
global gTime
while True:
money=random.randint(100,1000)
gLock.acquire()
if gTime>=gtotalTimes:
gLock.release()
break
gMoney+=money
print('%s生產了%d元,剩餘%d元錢'%(threading.current_thread(),money,gMoney))
gTime+=1
gLock.release()
time.sleep(0.5)
class Consumer(threading.Thread):
def run(self):
global gMoney
while True:
money=random.randint(100,1000)
gLock.acquire()
if gMoney>=money:
gMoney-=money
print("%s消費了%d元,剩餘%d元"%(threading.current_thread(),money,gMoney))
else:
if gTime>=gtotalTimes:
gLock.release()
break
print('%s消費者準備消費%d元,剩餘%d元,不足!'%(threading.current_thread(),money,gMoney))
gLock.release()
time.sleep(0.5)
def main():
for x in range(3):
t=Consumer(name='消費者線程%d'%x)
t.start()
for x in range(5):
t=Producer(name='生產者線程%d'%x)
t.start()
if __name__ == '__main__':
main()
五.condition版本的消費者和生產者模式。
爲了克服lock版本對cpu的損耗,我們採用threading.condition
1.acquire上鎖
2.release解鎖
3.wait:將該線程處於等待狀態,並且會釋放鎖,可以被notify,notify_all喚醒。
4.notify通知某個在等待進程,默認爲第一個。
5.notify_all:通知所有在等待的進程,並且notify_all和notify不會解鎖,應該啊在release前調用。
下面來看代碼:
import time
import threading
import random
gMoney=1000
gCondition=threading.Condition()
gtotalTimes=10
gTime=0
class Producer(threading.Thread):
def run(self):
global gMoney
global gTime
while True:
money=random.randint(100,1000)
gCondition.acquire()
if gTime>=gtotalTimes:
gCondition.release()
break
gMoney+=money
print('%s生產了%d元,剩餘%d元錢'%(threading.current_thread(),money,gMoney))
gTime+=1
gCondition.notify_all()#通知甦醒
gCondition.release()
time.sleep(0.5)
class Consumer(threading.Thread):
def run(self):
global gMoney
while True:
money=random.randint(100,1000)
gCondition.acquire()
while gMoney<money:
if gTime>=gtotalTimes:
return
print("%s準備消費%d元,剩餘%d元,不足!"%(threading.current_thread(),money,gMoney))
gCondition.wait()
print('%s消費了%d元,剩餘%d元'%(threading.current_thread(),money,gMoney))
gCondition.release()
time.sleep(0.5)
def main():
for x in range(3):
t=Consumer(name='消費者線程%d'%x)
t.start()
for x in range(5):
t=Producer(name='生產者線程%d'%x)
t.start()
if __name__ == '__main__':
main()
Queue線程安全隊列
加鎖是個經常的過程,如果你想把一些數據存儲到某個隊列,python內置queue模塊,其中Queue(先進先出),LiFoQueue(後進先出),可在多線程中使用,實現線程的同步。
1.q=Queue(3)#初始化創建一個先進先出隊列。
2.qsize(),返回隊列的大小。
3.empty()判斷是否爲空。
4.full() 判斷是否滿。
5.get() 按隊列規則取出數據。
6.put(),將數據放入隊列中。
下面看代碼:
from queue import Queue
import time
import threading
q=Queue(4)
# print(q.qsize())
# print(q.empty())
# for x in range(4):
# q.put(x)
# print()
# print(q.full())
# for x in range(4):
# print(q.get())
def set_value(q):
index=0
while True:
q.put(index)
index+=1
time.sleep(3)
def get_valuee(q):
while True:
print(q.get())
def main():
q=Queue(4)
t1=threading.Thread(target=set_value,args=[q])
t2=threading.Thread(target=get_valuee,args=[q])
t1.start()
t2.start()
if __name__ == '__main__':
main()