什麼是執行緒:
1.執行緒是cpu最小的執行單位
2.程序是資源單位
3.如果將作業系統比作工廠的話,程序是車間,執行緒是流水線,而cpu為電源
開啟乙個程序預設有乙個執行緒即主線程
執行緒的兩種開啟方式:①例項化thread類②自定義mythread類,繼承thread類,覆蓋run方法
什麼時候需要開啟多執行緒,什麼時候需要開啟多程序:
①當我們只有1個cpu即單核:
程序對於作業系統的資源耗費非常高,而執行緒相反會場低(比程序低10-100倍),只有乙個cpu的話,開啟多執行緒要比多程序效率更高
②當我們有多個cpu
1.當我們的多程序都是io時間較長時,開啟多程序和多執行緒沒有差別,因為cpu遇到io都會切換,io等待較長時,多程序和多執行緒都可以在等待時間內將其他非io程式完成
2.當我們的多程序都cpu密集型,即運算多時,多程序要比多執行緒運算的快
同乙個程序的多個執行緒是共享資源的
也就是說當我們多個執行緒對共有的資源修改時會導致資料的錯亂,故需要執行緒互斥鎖來保證資料安全,使用方法與程序鎖一樣
守護執行緒:
因為執行緒是共享資料資源的,為了保證資料安全,主線程會在所有子執行緒執行完畢後結束,故主線程的守護執行緒會在所有非守護執行緒執行完畢後結束
訊號量:
semaphore
互斥鎖是乙個種特殊的訊號量,即數量限制為1,
訊號量同一時刻可以允許規定數量的程式同時共享資料
生產者與消費者模型問題:
消費者不知道生產者何時生產完畢,一直在取容器中的產品消費,當生產者不再生產時,消費者會一直處於阻塞狀態
解決方法
①生產者在容器中放入none標記,當消費者獲取到none標記時,則停止從容器中取產品
併發的起動,但生產者要優先生產完畢,並根據消費者數量放入等額的none即停止標記
from threading import thread
import time,random
from multiprocessing import queue
q = queue()
def producter(name):
for i in range(5):
time.sleep(random.randint(1,2))
res = "%s的第%s個包子"%(name,i+1)
print("%s生產了第%s個包子"%(name,i+1))
q.put(res)
def customer(name):
while true:
time.sleep(random.randint(1,2))
res = q.get()
if not res :break
print("%s正在吃%s"%(name,res))
if __name__ == '__main__':
p1 = thread(target=producter,args = ("zb",))
p2 = thread(target=producter,args = ("xzh",))
p3 = thread(target=producter,args = ("lqq",))
c1 = thread(target=customer,args = ("egon",))
c2 = thread(target=customer,args = ("alex",))
p1.start()
p2.start()
p3.start()
c1.start()
c2.start()
p1.join()
p2.join()
p3.join()
q.put(none)
q.put(none)
②使用可join的佇列即joinablequeue
同理:讓生產者優先順序提高,先告知q.join()總產品的數量,當消費者獲取時產品,q.task_done(),給q.join()發乙個通知,
當數量吻合時,q.join()執行完畢,則主線程執行完畢,將消費者設定為主執行緒的守護執行緒,則消費者同時掛掉,不會再去獲取
from threading import thread
import time,random
from multiprocessing import joinablequeue
q = joinablequeue()
def producter(name):
for i in range(5):
time.sleep(random.randint(1,2))
res = "%s的第%s個包子"%(name,i+1)
print("%s生產了第%s個包子"%(name,i+1))
q.put(res)
def customer(name):
while true:
time.sleep(random.randint(1,2))
res = q.get()
if not res :break
print("%s正在吃%s"%(name,res))
q.task_done()
if __name__ == '__main__':
p1 = thread(target=producter,args = ("zb",))
p2 = thread(target=producter,args = ("xzh",))
p3 = thread(target=producter,args = ("lqq",))
c1 = thread(target=customer,args = ("egon",))
c2 = thread(target=customer,args = ("alex",))
p1.start()
p2.start()
p3.start()
c1.daemon =true
c1.start()
c2.daemon = true
c2.start()
p1.join()
p2.join()
p3.join()
q.join()
生產者消費者模型
1.生產者消費者問題 producer consumer 有限緩衝,多執行緒同步。生產者執行緒和消費者執行緒共享固定大小緩衝區。2.關鍵是保證生產者不會再緩衝區滿時加入資料,消費者不會在緩衝區空時消耗資料。3.解決辦法 讓生產者在緩衝區滿時休眠,等下次消費者消耗緩衝區中的資料的時候,生產者才能被喚醒...
生產者消費者模型
生產者與消費者 3,2,1 三種關係 生產者與消費者 互斥,同步 消費者與消費者 互斥 生產者與生產者 互斥 條件變數 int pthread cond destroy pthread cond t cond int pthread cond init pthread cond t restrict...
生產者消費者模型
當佇列滿時,生產者需要等待佇列有空間才能繼續往裡面放入商品,而在等待的期間內,生產者必須釋放對臨界資源 即佇列 的占用權。因為生產者如果不釋放對臨界資源的占用權,那麼消費者就無法消費佇列中的商品,就不會讓佇列有空間,那麼生產者就會一直無限等待下去。因此,一般情況下,當佇列滿時,會讓生產者交出對臨界資...