Python---多任务介绍以及Thread的基本使用
多任務(wù)介紹
現(xiàn)實(shí)生活中
有很多的場(chǎng)景中的事情是同時(shí)進(jìn)行的,比如開(kāi)車(chē)的時(shí)候 手和腳共同來(lái)駕駛汽車(chē),再比如唱歌跳舞也是同時(shí)進(jìn)行的;
想,如果把唱歌和跳舞這2件事情分開(kāi)依次完成的話,估計(jì)就沒(méi)有那么好的效果了(想一下場(chǎng)景:先唱歌,然后在跳舞,O(∩_∩)O哈哈~)
程序中
如下程序,來(lái)模擬“唱歌跳舞”這件事情
運(yùn)行結(jié)果如下:
注意
-
很顯然剛剛的程序并沒(méi)有完成唱歌和跳舞同時(shí)進(jìn)行的要求
-
如果想要實(shí)現(xiàn)“唱歌跳舞”同時(shí)進(jìn)行,那么就需要一個(gè)新的方法,叫做:多任務(wù)
多任務(wù)的概念
什么叫“多任務(wù)”呢?簡(jiǎn)單地說(shuō),就是操作系統(tǒng)可以同時(shí)運(yùn)行多個(gè)任務(wù)。打個(gè)比方,你一邊在用瀏覽器上網(wǎng),一邊在聽(tīng)MP3,一邊在用Word趕作業(yè),這就是多任務(wù),至少同時(shí)有3個(gè)任務(wù)正在運(yùn)行。還有很多任務(wù)悄悄地在后臺(tái)同時(shí)運(yùn)行著,只是桌面上沒(méi)有顯示而已。
現(xiàn)在,多核CPU已經(jīng)非常普及了,但是,即使過(guò)去的單核CPU,也可以執(zhí)行多任務(wù)。由于CPU執(zhí)行代碼都是順序執(zhí)行的,那么,單核CPU是怎么執(zhí)行多任務(wù)的呢?
答案就是操作系統(tǒng)輪流讓各個(gè)任務(wù)交替執(zhí)行,任務(wù)1執(zhí)行0.01秒,切換到任務(wù)2,任務(wù)2執(zhí)行0.01秒,再切換到任務(wù)3,執(zhí)行0.01秒……這樣反復(fù)執(zhí)行下去。表面上看,每個(gè)任務(wù)都是交替執(zhí)行的,但是,由于CPU的執(zhí)行速度實(shí)在是太快了,我們感覺(jué)就像所有任務(wù)都在同時(shí)執(zhí)行一樣。
真正的并行執(zhí)行多任務(wù)只能在多核CPU上實(shí)現(xiàn),但是,由于任務(wù)數(shù)量遠(yuǎn)遠(yuǎn)多于CPU的核心數(shù)量,所以,操作系統(tǒng)也會(huì)自動(dòng)把很多任務(wù)輪流調(diào)度到每個(gè)核心上執(zhí)行。
注意:
-
并發(fā):指的是任務(wù)數(shù)多余cpu核數(shù),通過(guò)操作系統(tǒng)的各種任務(wù)調(diào)度算法,實(shí)現(xiàn)用多個(gè)任務(wù)“一起”執(zhí)行(實(shí)際上總有一些任務(wù)不在執(zhí)行,因?yàn)榍袚Q任務(wù)的速度相當(dāng)快,看上去一起執(zhí)行而已)
-
并行:指的是任務(wù)數(shù)小于等于cpu核數(shù),即任務(wù)真的是一起執(zhí)行的
線程(重點(diǎn))
python的thread模塊是比較底層的模塊,python的threading模塊是對(duì)thread做了一些包裝的,可以更加方便的被使用
1. 使用threading模塊
單線程執(zhí)行
運(yùn)行結(jié)果:
多線程執(zhí)行
運(yùn)行結(jié)果:
說(shuō)明
-
可以明顯看出使用了多線程并發(fā)的操作,花費(fèi)時(shí)間要短很多
-
當(dāng)調(diào)用start()時(shí),才會(huì)真正的創(chuàng)建線程,并且開(kāi)始執(zhí)行
2. 主線程會(huì)等待所有的子線程結(jié)束后才結(jié)束
''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)! ''' #coding=utf-8 import threading from time import sleep,ctimedef sing():for i in range(3):print("正在唱歌...%d"%i)sleep(1)def dance():for i in range(3):print("正在跳舞...%d"%i)sleep(1)if __name__ == '__main__':print('---開(kāi)始---:%s'%ctime())t1 = threading.Thread(target=sing)t2 = threading.Thread(target=dance)t1.start()t2.start()#sleep(5) # 屏蔽此行代碼,試試看,程序是否會(huì)立馬結(jié)束?print('---結(jié)束---:%s'%ctime())
3. 查看線程數(shù)量
線程(注意點(diǎn))
1. 線程執(zhí)行代碼的封裝
通過(guò)上一小節(jié),能夠看出,通過(guò)使用threading模塊能完成多任務(wù)的程序開(kāi)發(fā),為了讓每個(gè)線程的封裝性更完美,所以使用threading模塊時(shí),往往會(huì)定義一個(gè)新的子類(lèi)class,只要繼承threading.Thread就可以了,然后重寫(xiě)run方法
示例如下:
''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)! ''' #coding=utf-8 import threading import timeclass MyThread(threading.Thread):def run(self):for i in range(3):time.sleep(1)msg = "I'm "+self.name+' @ '+str(i) #name屬性中保存的是當(dāng)前線程的名字print(msg)if __name__ == '__main__':t = MyThread()t.start()
說(shuō)明
python的threading.Thread類(lèi)有一個(gè)run方法,用于定義線程的功能函數(shù),可以在自己的線程類(lèi)中覆蓋該方法。而創(chuàng)建自己的線程實(shí)例后,通過(guò)Thread類(lèi)的start方法,可以啟動(dòng)該線程,交給python虛擬機(jī)進(jìn)行調(diào)度,當(dāng)該線程獲得執(zhí)行的機(jī)會(huì)時(shí),就會(huì)調(diào)用run方法執(zhí)行線程。
2. 線程的執(zhí)行順序
''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)! ''' #coding=utf-8 import threading import timeclass MyThread(threading.Thread):def run(self):for i in range(3):time.sleep(1)msg = "I'm "+self.name+' @ '+str(i)print(msg) def test():for i in range(5):t = MyThread()t.start() if __name__ == '__main__':test()執(zhí)行結(jié)果:(運(yùn)行的結(jié)果可能不一樣,但是大體是一致的)
I'm Thread-1 @ 0I'm Thread-2 @ 0I'm Thread-5 @ 0I'm Thread-3 @ 0I'm Thread-4 @ 0I'm Thread-3 @ 1I'm Thread-4 @ 1I'm Thread-5 @ 1I'm Thread-1 @ 1I'm Thread-2 @ 1I'm Thread-4 @ 2I'm Thread-5 @ 2I'm Thread-2 @ 2I'm Thread-1 @ 2I'm Thread-3 @ 2說(shuō)明
從代碼和執(zhí)行結(jié)果我們可以看出,多線程程序的執(zhí)行順序是不確定的。當(dāng)執(zhí)行到sleep語(yǔ)句時(shí),線程將被阻塞(Blocked),到sleep結(jié)束后,線程進(jìn)入就緒(Runnable)狀態(tài),等待調(diào)度。
而線程調(diào)度將自行選擇一個(gè)線程執(zhí)行。上面的代碼中只能保證每個(gè)線程都運(yùn)行完整個(gè)run函數(shù),但是線程的啟動(dòng)順序、run函數(shù)中每次循環(huán)的執(zhí)行順序都不能確定。
3. 總結(jié)
每個(gè)線程默認(rèn)有一個(gè)名字,盡管上面的例子中沒(méi)有指定線程對(duì)象的name,但是python會(huì)自動(dòng)為線程指定一個(gè)名字。
當(dāng)線程的run()方法結(jié)束時(shí)該線程完成。
無(wú)法控制線程調(diào)度程序,但可以通過(guò)別的方式來(lái)影響線程調(diào)度的方式。
總結(jié)
以上是生活随笔為你收集整理的Python---多任务介绍以及Thread的基本使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 说说几个 Python 内存分配时的小秘
- 下一篇: Python---udp绑定信息以及网络