線程
多線程--threading
python的thread模塊是比較底層的模塊,python的threading模塊是對thread做了一些包裝的檀何,可以更加方便的被使用
使用threading模塊
importthreading
importtime
defsaySorry():
print("親愛的奇昙,我錯了,我能吃飯了嗎?")
time.sleep(1)
if__name__ =="__main__":
foriinrange(5):
t = threading.Thread(target=saySorry)
t.start()#啟動線程缩搅,即讓線程開始執(zhí)行
多線程并發(fā)操作,話費的時間要短很多
創(chuàng)建好的線程,需要調(diào)用start()方法來啟動
主線程會等愛所有的子線程結(jié)束后才結(jié)束
多線程和多進程一樣,執(zhí)行順序是不確定的人,如果線程被sleep阻塞,到結(jié)束的時候線程進入就緒狀態(tài)
每個線程會有一個名字,python會自動為線程指定一個名字
當線程的run()方法結(jié)束時該線程完成
線程的集中狀態(tài):
總結(jié):
在一個進程內(nèi)的所有線程共享全局變量,能夠在不適用其他方式的前提下完成多線程間的數(shù)據(jù)共享
缺點:
線程對全局變量隨意更改可能會造成多線程之間對全局變量的混亂(線程非安全)
進程和線程:
進程:能夠完成多任務(wù),比如在一臺電腦上能夠同時運行多個QQ
線程:能夠完成多個任務(wù),比如一個qq的多個聊天窗口
定義的不同
·進程是系統(tǒng)進行資源分配和調(diào)度的一個獨立單位.
·線程是進程的一個實體,是CPU調(diào)度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(如程序計數(shù)器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源.
區(qū)別:
一個程序至少有一個進程,一個進程至少有一個線程
線程的劃分尺度少于進程(資源比進程少),使得多線程程序的并發(fā)性高,
進程在執(zhí)行過程中擁有獨立的內(nèi)存單元,而對歌線程共享內(nèi)存,從而極大的提高了程序的運行效率
線程不能夠獨立執(zhí)行,必須依存在進程中
優(yōu)缺點:
線程和進城在使用上各有優(yōu)缺點,線程執(zhí)行開銷小,但不利于資源的管理和保護,而進程正好相反
同步的概念:
多線程開發(fā)可能遇到的問題
同步就是協(xié)同步調(diào),按預(yù)定的先后次序進運行
互斥鎖:
當多個線程幾乎同時修改某一個共享數(shù)據(jù)的時候需要進行同步控制
線程同步能夠保證多個線程安全訪問競爭資源冻辩,最簡單的同步機制是引入互斥鎖
互斥鎖為資源引入一個狀態(tài)猖腕,鎖定/非鎖定
某個線程要更改共享數(shù)據(jù)時,先將其鎖定恨闪,此時資源的狀態(tài)為'鎖定',其他線程不能更改,知道該線程釋放資源,其他線程才能再次鎖定該資源
threading.Lock
其中,鎖定方法acquire可以有一個bloching參數(shù).
如果設(shè)定blocking為true,則當前線程會堵塞,知道獲取到這個鎖為止,默認為true,如果設(shè)定為false,則當前線程不會堵塞
threading.enumerate(): 返回一個包含正在運行的線程的list倘感。正在運行指線程啟動后、結(jié)束前咙咽,不包括啟動前和終止后的線程老玛。
threading.activeCount(): 返回正在運行的線程數(shù)量,與len(threading.enumerate())有相同的結(jié)果。
除了使用方法外蜡豹,線程模塊同樣提供了Thread類來處理線程麸粮,Thread類提供了以下方法:
run(): 用以表示線程活動的方法。
start():啟動線程活動余素。
join([time]): 等待至線程中止豹休。這阻塞調(diào)用線程直至線程的join() 方法被調(diào)用中止-正常退出或者拋出未處理的異常-或者是可選的超時發(fā)生。
isAlive(): 返回線程是否活動的桨吊。
getName(): 返回線程名威根。
setName(): 設(shè)置線程名。
注意:
每次只有一個線程可以獲得鎖,如果此時另一個線程試圖獲得這個鎖,該線程就會變成阻塞狀態(tài),只懂啊擁有鎖的方法釋放鎖之后
好處:確保關(guān)鍵代碼完整執(zhí)行:
壞處:
阻止并發(fā)執(zhí)行,使效率降低
可能會造成死鎖
多線程,局部數(shù)據(jù)
在多線程開發(fā)中,全局變量是多個線程都共享的數(shù)據(jù),而局部變量等是各自線程的,非共享
死鎖
兩個線程同時等待對方的資源,就會造成死鎖
盡量避免(銀行家算法)
添加超時時間
queue的說明:
添加數(shù)據(jù)到隊列中,使用put()方法
Queue.qsize() 返回隊列的大小
Queue.empty() 如果隊列為空视乐,返回True,反之False
Queue.full() 如果隊列滿了洛搀,返回True,反之False
Queue.full 與 maxsize 大小對應(yīng)
Queue.get([block[, timeout]])獲取隊列,timeout等待時間
Queue.get_nowait() 相當Queue.get(False)
Queue.put(item) 寫入隊列佑淀,timeout等待時間
Queue.put_nowait(item) 相當Queue.put(item, False)
Queue.task_done() 在完成一項工作之后留美,Queue.task_done()函數(shù)向任務(wù)已經(jīng)完成的隊列發(fā)送一個信號
Queue.join() 實際上意味著等到隊列為空,再執(zhí)行別的操作
伸刃、生產(chǎn)者消費者模式:
生產(chǎn)者消費者模式是通過一個容器來解決生產(chǎn)者和消費者的強耦合問題谎砾。生產(chǎn)者和消費者彼此之間不直接通訊,而通過阻塞隊列來進行通訊捧颅,所以生產(chǎn)者生產(chǎn)完數(shù)據(jù)之后不用等待消費者處理景图,直接扔給阻塞隊列,消費者不找生產(chǎn)者要數(shù)據(jù)碉哑,而是直接從阻塞隊列里取挚币,阻塞隊列就相當于一個緩沖區(qū),平衡了生產(chǎn)者和消費者的處理能力扣典。
這個阻塞隊列就是用來給生產(chǎn)者和消費者解耦的妆毕。縱觀大多數(shù)設(shè)計模式贮尖,都會找一個第三者出來進行解耦