Python爬蟲(chóng)程序設(shè)計(jì)KC33_第1頁(yè)
Python爬蟲(chóng)程序設(shè)計(jì)KC33_第2頁(yè)
Python爬蟲(chóng)程序設(shè)計(jì)KC33_第3頁(yè)
Python爬蟲(chóng)程序設(shè)計(jì)KC33_第4頁(yè)
Python爬蟲(chóng)程序設(shè)計(jì)KC33_第5頁(yè)
已閱讀5頁(yè),還剩15頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、3.3.1 Python的前后臺(tái)線程線程類(lèi)似于同時(shí)執(zhí)行多個(gè)不同程序,多線程運(yùn)行有如下優(yōu)點(diǎn):使用線程可以把占據(jù)長(zhǎng)時(shí)間的程序中的任務(wù)放到后臺(tái)去處理。程序的運(yùn)行速度可能加快在一些等待的任務(wù)實(shí)現(xiàn)上如用戶輸入、文件讀寫(xiě)和網(wǎng)絡(luò)收發(fā)數(shù)據(jù)等,線程就比較有用了。在這種情況下我們可以釋放一些珍貴的資源如內(nèi)存占用等等。每個(gè)線程都有他自己的一組CPU寄存器,稱(chēng)為線程的上下文,該上下文反映了線程上次運(yùn)行該線程的CPU寄存器的狀態(tài)。在其他線程正在運(yùn)行時(shí),線程可以暫時(shí)擱置(也稱(chēng)為睡眠), 這就是線程的退讓。3.3.1 Python的前后臺(tái)線程在Python中要啟動(dòng)一個(gè)線程,可以使用threading包中的Thread建立一

2、個(gè)對(duì)象,這個(gè)Thread類(lèi)的基本原型是:t=Thread(target,args=None)其中target是要執(zhí)行的線程函數(shù),args是一個(gè)元組或者列表為target的函數(shù)提供參數(shù),然后調(diào)用t.start()就開(kāi)始了線程。例3-3-1: 在主線程中啟動(dòng)一個(gè)子線程執(zhí)行reading函數(shù)。import threadingimport timeimport randomdef reading(): for i in range(10): print(reading,i) time.sleep(random.randint(1,2)r=threading.Thread(target=reading)

3、r.setDaemon(False)r.start()print(The End)程序結(jié)果:reading 0The Endreading 1reading 2reading 3reading 4從結(jié)果看到主線程啟動(dòng)子線程r后就結(jié)束了,但是子線程還沒(méi)有結(jié)束,繼續(xù)顯示完reasing 4后才結(jié)束。其中的r.setDaemon(False)就是設(shè)置線程r為后臺(tái)線程,后臺(tái)線程不因主線程的結(jié)束而結(jié)束。如何設(shè)置r.setDaemon(True),那么r就是前臺(tái)線程。例3-3-2: 啟動(dòng)一個(gè)前臺(tái)線程import threadingimport timeimport randomdef reading():

4、 for i in range(5): print(reading,i) time.sleep(random.randint(1,2)r=threading.Thread(target=reading)r.setDaemon(True)r.start()print(The End)程序結(jié)果:reading 0The End由此可見(jiàn)在主線程結(jié)束后子線程也結(jié)束,這就是前臺(tái)線程。例3-3-3:前臺(tái)與后臺(tái)線程import threadingimport timeimport randomdef reading(): for i in range(5): print(reading,i) time.sl

5、eep(random.randint(1,2)def test(): r=threading.Thread(target=reading) r.setDaemon(True) r.start() print(test end)t=threading.Thread(target=test)t.setDaemon(False)t.start()print(The End)程序結(jié)果:The Endreading 0test end由此可見(jiàn)主線程啟動(dòng)后臺(tái)子線程t后就結(jié)束了,但是t還在執(zhí)行,在t中啟動(dòng)前臺(tái)r子線程,之后t結(jié)束,相應(yīng)的r也結(jié)束。3.3.2 線程的等待3.3.2 線程的等待在多線程的程序中往

6、往一個(gè)線程(例如主線程)要等待其它線程執(zhí)行完畢才繼續(xù)執(zhí)行,這可以用join函數(shù),使用的方法是:線程對(duì)象.join()在一個(gè)線程代碼中執(zhí)行這條語(yǔ)句,當(dāng)前的線程就會(huì)停止執(zhí)行,一直等到指定的線程對(duì)象的線程執(zhí)行完畢后才繼續(xù)執(zhí)行,即這條語(yǔ)句啟動(dòng)阻塞等待的作用。例3-3-4:主線程啟動(dòng)一個(gè)子線程并等待子線程結(jié)束后才繼續(xù)執(zhí)行。import threadingimport timeimport randomdef reading(): for i in range(5): print(reading,i) time.sleep(random.randint(1,2)t=threading.Thread(tar

7、get=reading)t.setDaemon(False)t.start()t.join()print(The End)程序結(jié)果:reading 0reading 1reading 2reading 3reading 4The End由此可見(jiàn)主線程啟動(dòng)子線程t執(zhí)行reading函數(shù),t.join()就阻塞主線程,一直等到t線程執(zhí)行完畢后才結(jié)束t.join(),繼續(xù)執(zhí)行顯示The End。例3-3-5:在一個(gè)子線程啟動(dòng)另外一個(gè)子線程,并等待子線程結(jié)束后才繼續(xù)執(zhí)行。import threadingimport timeimport randomdef reading(): for i in ra

8、nge(5): print(reading,i) time.sleep(random.randint(1,2)def test(): r=threading.Thread(target=reading) r.setDaemon(True) r.start() r.join() print(test end)t=threading.Thread(target=test)t.setDaemon(False)t.start()t.join()print(The End)程序結(jié)果:reading 0reading 1reading 2reading 3reading 4test endThe End由

9、此可見(jiàn)主線程啟動(dòng)t線程后t.join()會(huì)等待t線程結(jié)束,在test中再次啟動(dòng)r子線程,而且r.join()而阻塞t線程,等待r線程執(zhí)行完畢后才結(jié)束r.join(),然后顯示test end,之后t線程結(jié)束,再次結(jié)束t.join(),主線程顯示The End后結(jié)束。3.3.3 多線程與資源3.3.3 多線程與資源在多個(gè)線程的程序中一個(gè)普遍存在的問(wèn)題是,如果多個(gè)線程要競(jìng)爭(zhēng)同時(shí)訪問(wèn)與改寫(xiě)公共資源,那么應(yīng)該怎么樣協(xié)調(diào)各個(gè)線程的關(guān)系。一個(gè)普遍使用的方法是使用線程鎖,Python使用threading.RLock類(lèi)來(lái)創(chuàng)建一個(gè)線程鎖對(duì)象:lock=threading.RLock()這個(gè)對(duì)象lock有兩個(gè)重

10、要方法是acquire()與release() 。當(dāng)執(zhí)行:lock.acquire()語(yǔ)句時(shí)強(qiáng)迫lock獲取線程鎖,如果已經(jīng)有另外的線程先調(diào)用了acquire()方法獲取了線程鎖而還沒(méi)有調(diào)用release()釋放鎖,那么這個(gè)lock.acquire()就阻塞當(dāng)前的線程,一直等待鎖的控制權(quán),直到別的線程釋放鎖后lock.acquire()就獲取鎖并解除阻塞,線程繼續(xù)執(zhí)行,執(zhí)行后線程要調(diào)用lock.release()釋放鎖,不然別的線程會(huì)一直得不到鎖的控制權(quán)使用acquire /release的工作機(jī)制我們可以把一段修改公共資源的代碼用acquire()與release()夾起來(lái),這樣就保證一次最

11、多只有一個(gè)線程在修改公共資源,別的線程如果也要修改就必須等待,直到本線程調(diào)用release()釋放鎖后別的線程才能獲取鎖的控制權(quán)進(jìn)行資源的修改。例3-3-6:一個(gè)子線程A把一個(gè)全局的列表words進(jìn)行升序的排列,另外一個(gè)D線程把這個(gè)列表進(jìn)行降序的排列。import threadingimport timelock=threading._RLock()words=a,b,d,b,p,m,e,f,bdef increase(): global words for count in range(5): lock.acquire() print(A acquired) for i in range(l

12、en(words): for j in range(i+1,len(words): if wordsjwordsi: t=wordsi wordsi=wordsj wordsj=t print(D ,words) time.sleep(1) lock.release()A=threading.Thread(target=increase)A.setDaemon(False)A.start()D=threading.Thread(target=decrease)D.setDaemon(False)D.start()print(The End)程序結(jié)果:A acquiredA a, b, b, b, d, e, f, m, pThe EndD acquiredD p, m, f, e, d, b, b, b, aD acquiredD p, m, f, e, d, b, b, b, aA acquiredA a, b, b, b, d, e, f, m, pA acquiredA a, b, b, b, d, e, f, m, pD acquiredD p, m, f, e, d, b, b, b, aD acquiredD p, m, f, e, d, b, b, b, aD acqui

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論