摘要:中的多線程我參考了中的介紹,介紹的很入門很詳細(xì)。如只設(shè)置了第個(gè)和第個(gè),沒有設(shè)置這只會(huì)掉第個(gè)子線程個(gè)人猜測,當(dāng)程序運(yùn)行完主線程后則會(huì)檢查剩余的子線程,將最后面的且是子進(jìn)程刪掉。第個(gè)沒有掉是因?yàn)榫€程還在運(yùn)行并且是默認(rèn)狀態(tài)不能被的。
本人初學(xué)者開始第一篇博客,記錄學(xué)習(xí)的點(diǎn)點(diǎn)滴滴,以作為備忘錄,也希望能同大家一起分享。有理解錯(cuò)誤的地方希望大家指正。 python中的多線程我參考了(http://www.cnblogs.com/fnng/p...)中的介紹,介紹的很入門很詳細(xì)。介紹了threading的基本用法。
最簡單的情況是:
import threading import time def fuction(i): print("我是第%s個(gè)進(jìn)程,開始時(shí)間是%s"%(i+1,time.ctime())) time.sleep(2) #子程序等2秒。。 print("我是第%s個(gè)進(jìn)程,結(jié)束時(shí)間是%s"%(i+1,time.ctime())) threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)] for t in threads: t.start() print("程序結(jié)束,%s:"%(time.ctime())) #輸出為------------------- 我是第1個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 17:45:37 2017 我是第2個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 17:45:37 2017 我是第3個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 17:45:37 2017 我是第4個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 17:45:37 2017 我是第5個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 17:45:37 2017 **程序結(jié)束,Sun Oct 22 17:45:37 2017:** #主線程繼續(xù)執(zhí)行,不等待,也不殺死子線程 我是第1個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 17:45:39 2017 我是第2個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 17:45:39 2017 我是第5個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 17:45:39 2017 我是第3個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 17:45:39 2017 我是第4個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 17:45:39 2017
這里介紹另外兩個(gè)函數(shù):setDaemon()、join()
join:如在一個(gè)線程B中調(diào)用threada.join(),則threada結(jié)束后,線程B才會(huì)接著threada.join()往后運(yùn)行。
setDaemon:主線程A啟動(dòng)了子線程B,調(diào)用b.setDaemaon(True),則主線程結(jié)束時(shí),會(huì)把子線程B也殺死,與C/C++中得默認(rèn)效果是一樣的。
比如我想讓主程序等待子程序完成之后再運(yùn)行,可以是用t.join()
其中t是指某個(gè)子進(jìn)程,如t1,t2....然后join()可以有一個(gè)參數(shù),主進(jìn)程等待多少秒,如t1.join(2)指在t1子進(jìn)程開始后,主進(jìn)程等待2秒就繼續(xù)執(zhí)行。
def fuction(i): print("我是第%s個(gè)進(jìn)程,開始時(shí)間是%s"%(i+1,time.ctime())) time.sleep(i*2) #模擬子進(jìn)程的運(yùn)行時(shí)間,ID越大時(shí)間越長 print("我是第%s個(gè)進(jìn)程,結(jié)束時(shí)間是%s"%(i+1,time.ctime())) threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)] for t in threads: t.start() threads[1].join(1) #主進(jìn)程在第二個(gè)子進(jìn)程開始后阻塞1秒再運(yùn)行 print("主進(jìn)程:,%s:"%(time.ctime())) #輸出--------------------- 我是第1個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 18:12:14 2017 我是第1個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 18:12:14 2017 我是第2個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 18:12:14 2017 #第二個(gè)子進(jìn)程14秒開始 我是第3個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 18:12:14 2017 我是第4個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 18:12:14 2017 我是第5個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 18:12:14 2017 主進(jìn)程:Sun Oct 22 18:12:15 2017: #主進(jìn)程在阻塞一秒后的15秒開始啟動(dòng)運(yùn)行 我是第2個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 18:12:16 2017 我是第3個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 18:12:18 2017 我是第4個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 18:12:20 2017 我是第5個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 18:12:22 2017
若想等所有的子進(jìn)程都完成后,主進(jìn)程在進(jìn)行可以,簡單情況可以用最慢的一個(gè)子進(jìn)程來對主進(jìn)程進(jìn)行阻塞,這里最慢的是第5個(gè)子進(jìn)程??梢裕簍hreads[4].join()。
import tensorflow as tf import numpy as np import random import threading import time def fuction(i): print("我是第%s個(gè)進(jìn)程,開始時(shí)間是%s"%(i+1,time.ctime())) time.sleep((i+0.5)*2) #模擬子程序運(yùn)行隨機(jī)秒 print("我是第%s個(gè)進(jìn)程,結(jié)束時(shí)間是%s"%(i+1,time.ctime())) threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)] for t in threads: t.start() threads[4].join() print("主進(jìn)程:%s:"%(time.ctime())) #輸出----------------------- 我是第1個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 18:29:28 2017 我是第2個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 18:29:28 2017 我是第3個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 18:29:28 2017 我是第4個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 18:29:28 2017 我是第5個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 18:29:28 2017 我是第1個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 18:29:29 2017 我是第2個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 18:29:31 2017 我是第3個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 18:29:33 2017 我是第4個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 18:29:35 2017 我是第5個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 18:29:37 2017 主進(jìn)程:Sun Oct 22 18:29:37 2017: #主進(jìn)程等到最后一個(gè)子進(jìn)程結(jié)束后才運(yùn)行
另一種情況是,比如我想讓主程序運(yùn)行完就立刻結(jié)束,殺死子程序:可以用t.setDaemon(True)
def fuction(i): print("我是第%s個(gè)進(jìn)程,開始時(shí)間是%s"%(i+1,time.ctime())) time.sleep((i+0.5)*2) #模擬子程序運(yùn)行隨機(jī)秒 print("我是第%s個(gè)進(jìn)程,結(jié)束時(shí)間是%s"%(i+1,time.ctime())) threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)] for t in threads: t.setDaemon(True) t.start() print("主進(jìn)程:%s:"%(time.ctime())) #輸出--------------------------------- 我是第1個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:04:06 2017 我是第2個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:04:06 2017 我是第3個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:04:06 2017 我是第4個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:04:06 2017 我是第5個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:04:06 2017 主進(jìn)程:Sun Oct 22 19:04:06 2017: #可以看到主線程完成后,后面就沒有子線程了。
一種特殊情況請注意:當(dāng)并非像上面每個(gè)子進(jìn)程一樣都設(shè)置t.setDaemon(True)(有的設(shè)置有的沒有。。)
如:
threads[2].setDaemon(True) #只設(shè)置了第3個(gè)和第5個(gè),1,2,4沒有設(shè)置這只會(huì)kill掉第5個(gè)子線程 #個(gè)人猜測,當(dāng)程序運(yùn)行完主線程后則會(huì)檢查剩余的子線程,將最后面的 threads[4].setDaemon(True) #且是setDaemon(True) 子進(jìn)程刪掉。第3個(gè)沒有kill掉是因?yàn)?線程還在運(yùn)行 for t in threads: #并且4是默認(rèn)狀態(tài)不能被kill的。這時(shí)主進(jìn)程依然在等待4完成而不會(huì) t.start() #殺掉剩余進(jìn)程,當(dāng)4完成了,就不等待了直接殺掉剩余進(jìn)程
我們可以這樣驗(yàn)證,在線程4結(jié)束前看看線程5是否存活:
import tensorflow as tf import numpy as np import random import threading import time def fuction(i): print("我是第%s個(gè)進(jìn)程,開始時(shí)間是%s"%(i+1,time.ctime())) time.sleep((i+0.5)*2) #模擬子程序運(yùn)行隨機(jī)秒 print("我是第%s個(gè)進(jìn)程,結(jié)束時(shí)間是%s"%(i+1,time.ctime())) if i ==3: print("我是第4個(gè)進(jìn)程:結(jié)束前進(jìn)程5的狀態(tài)是:" ,threads[4].is_alive()) #加這一句判斷現(xiàn)成物 #的存活情況 threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)] #threads[0].setDaemon(True) #threads[1].setDaemon(True) threads[2].setDaemon(True) #threads[3].setDaemon(True) threads[4].setDaemon(True) for t in threads: t.start() print("主進(jìn)程:%s:"%(time.ctime())) #輸出---------------------------------- 我是第1個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:22:36 2017 我是第2個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:22:36 2017 我是第3個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:22:36 2017 我是第4個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:22:36 2017 我是第5個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:22:36 2017 主進(jìn)程:Sun Oct 22 19:22:36 2017: 我是第1個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 19:22:37 2017 我是第2個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 19:22:39 2017 我是第3個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 19:22:41 2017 我是第4個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 19:22:43 2017 我是第4個(gè)進(jìn)程:結(jié)束前進(jìn)程5的狀態(tài)是: True #可以看到,此時(shí)線程5還是存活的,但4結(jié)束后5就消失了。
最后一種應(yīng)用時(shí),我們希望主程序等待某幾個(gè)子線程先執(zhí)行完后在運(yùn)行,并且殺死剩余沒有完成的程序,可以用setDaemon()、join() 組合的方式:
如:完整運(yùn)行完第1,2,3線程,之后運(yùn)行主線程,主線程完成后殺死剩余的子線程:
def fuction(i): print("我是第%s個(gè)進(jìn)程,開始時(shí)間是%s"%(i+1,time.ctime())) time.sleep((i+0.5)*2) #模擬子程序運(yùn)行隨機(jī)秒 print("我是第%s個(gè)進(jìn)程,結(jié)束時(shí)間是%s"%(i+1,time.ctime())) if i ==3: print("我是第4個(gè)進(jìn)程:結(jié)束前進(jìn)程5的狀態(tài)是:" ,threads[4].is_alive()) threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)] #threads[0].setDaemon(True) #threads[1].setDaemon(True) #threads[2].setDaemon(True) threads[3].setDaemon(True) #設(shè)置第4和5子線程為可以kill的線程 threads[4].setDaemon(True) for t in threads: t.start() threads[0].join() #設(shè)置第1,2,3線程阻塞主線程的子線程 threads[1].join() threads[2].join() print("主進(jìn)程:%s:"%(time.ctime())) #輸出-------------------------- 我是第1個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:32:24 2017 我是第2個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:32:24 2017 我是第3個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:32:24 2017 我是第4個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:32:24 2017 我是第5個(gè)進(jìn)程,開始時(shí)間是Sun Oct 22 19:32:24 2017 我是第1個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 19:32:25 2017 我是第2個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 19:32:27 2017 我是第3個(gè)進(jìn)程,結(jié)束時(shí)間是Sun Oct 22 19:32:29 2017 主進(jìn)程:Sun Oct 22 19:32:29 2017: #我們可以看到只完成了第1,2,3線程,然后最后是主線程
這篇文章就到這里,python中子線程的暫停,阻塞,關(guān)閉,和喚醒,本人都不是很明確,如有好方法希望大家一起交流。我先寫在這里。對于tensorflow中的讀取數(shù)據(jù)線程控制,等我整理在下一篇博客。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/40938.html
摘要:進(jìn)程可創(chuàng)建多個(gè)線程來執(zhí)行同一程序的不同部分。就緒等待線程調(diào)度。運(yùn)行線程正常運(yùn)行阻塞暫停運(yùn)行,解除阻塞后進(jìn)入狀態(tài)重新等待調(diào)度。消亡線程方法執(zhí)行完畢返回或者異常終止。多線程多的情況下,依次執(zhí)行各線程的方法,前頭一個(gè)結(jié)束了才能執(zhí)行后面一個(gè)。 淺談Python多線程 作者簡介: 姓名:黃志成(小黃)博客: 博客 線程 一.什么是線程? 操作系統(tǒng)原理相關(guān)的書,基本都會(huì)提到一句很經(jīng)典的話: 進(jìn)程...
摘要:多線程的理解多進(jìn)程和多線程都可以執(zhí)行多個(gè)任務(wù),線程是進(jìn)程的一部分。多線程創(chuàng)建在中,同樣可以實(shí)現(xiàn)多線程,有兩個(gè)標(biāo)準(zhǔn)模塊和,不過我們主要使用更高級的模塊。多線程的應(yīng)用場景。 1、多線程的理解 多進(jìn)程和多線程都可以執(zhí)行多個(gè)任務(wù),線程是進(jìn)程的一部分。線程的特點(diǎn)是線程之間可以共享內(nèi)存和變量,資源消耗少(不過在Unix環(huán)境中,多進(jìn)程和多線程資源調(diào)度消耗差距不明顯,Unix調(diào)度較快),缺點(diǎn)是線程之間...
摘要:在一個(gè)進(jìn)程內(nèi)部,要同時(shí)干多件事,就需要同時(shí)運(yùn)行多個(gè)子任務(wù),我們把進(jìn)程內(nèi)的這些子任務(wù)稱為線程??偨Y(jié)一下,多任務(wù)的實(shí)現(xiàn)方式有三種多進(jìn)程模式多線程模式多進(jìn)程多線程模式線程是最小的執(zhí)行單元,而進(jìn)程由至少一個(gè)線程組成。 進(jìn)程與線程 很多同學(xué)都聽說過,現(xiàn)代操作系統(tǒng)比如Mac OS X,UNIX,Linux,Windows等,都是支持多任務(wù)的操作系統(tǒng)。 什么叫多任務(wù)呢?簡單地說,就是操作系統(tǒng)可以同時(shí)...
摘要:也提供多線程支持,而且中的線程并非是模擬出來的多線程,而是系統(tǒng)級別的標(biāo)準(zhǔn)庫提供了兩個(gè)模塊和。同一個(gè)變量,線程則會(huì)互相共享。例如多個(gè)線程對銀行中的某一個(gè)賬戶進(jìn)行操作。但是實(shí)際情況是隨意切換線程。說到的多線程編程,就會(huì)繞不過。 該文章參考了http://www.liaoxuefeng.com/wi... 廖雪峰的教程。 一個(gè)進(jìn)程至少有一個(gè)線程。Python也提供多線程支持,而且Python...
摘要:所以與多線程相比,線程的數(shù)量越多,協(xié)程性能的優(yōu)勢越明顯。值得一提的是,在此過程中,只有一個(gè)線程在執(zhí)行,因此這與多線程的概念是不一樣的。 真正有知識(shí)的人的成長過程,就像麥穗的成長過程:麥穗空的時(shí)候,麥子長得很快,麥穗驕傲地高高昂起,但是,麥穗成熟飽滿時(shí),它們開始謙虛,垂下麥芒。 ——蒙田《蒙田隨筆全集》 上篇論述了關(guān)于python多線程是否是雞肋的問題,得到了一些網(wǎng)友的認(rèn)可,當(dāng)然也有...
摘要:批評的人通常都會(huì)說的多線程編程太困難了,眾所周知的全局解釋器鎖,或稱使得多個(gè)線程的代碼無法同時(shí)運(yùn)行。多線程起步首先讓我們來創(chuàng)建一個(gè)名為的模塊。多進(jìn)程可能比多線程更易使用,但需要消耗更大的內(nèi)存。 批評 Python 的人通常都會(huì)說 Python 的多線程編程太困難了,眾所周知的全局解釋器鎖(Global Interpreter Lock,或稱 GIL)使得多個(gè)線程的 Python 代碼無...
閱讀 3524·2021-09-08 09:36
閱讀 2690·2019-08-30 15:54
閱讀 2412·2019-08-30 15:54
閱讀 1820·2019-08-30 15:44
閱讀 2446·2019-08-26 14:04
閱讀 2489·2019-08-26 14:01
閱讀 2932·2019-08-26 13:58
閱讀 1414·2019-08-26 13:47