Python多線程(二):多線程編程

上一篇:GIL

多線程編程有兩種方式,一種是通過Thread類對線程進行實例化睬涧,另外一種是通過繼承Thread類并重寫其run方法。

通過Thread類實例化進行多線程編程

下面是一個例子:

import threading
import time

def do_something(content, sec):
    print('%s started' % content)
    time.sleep(sec)
    print('%s completed' % content)

def main():
    thread1 = threading.Thread(target=do_something, args=('First task', 2))
    thread2 = threading.Thread(target=do_something, args=('Second task', 4))
    start_time = time.time()
    thread1.start()
    thread2.start()
    print('Last time: %fs' % (time.time() - start_time))

main()

從這個例子中我們可以很容易地看出如果用Thread類實例化的方式創(chuàng)建線程沛厨,并通過start()方法開始線程宙地。
結(jié)果輸入如下:

First task started
Second task started
Last time: 0.000294s
First task completed
Second task completed

為什么這里的時間會是0s呢?原因是因為當我們創(chuàng)建了兩個線程并啟動后逆皮,此時的程序共有三個線程宅粥,thread1thread2為子線程,main函數(shù)的線程被稱為主線程电谣,可在線程內(nèi)部通過threading.current_thread()來獲取當前線程信息秽梅,主線程會默認明名為'MainThread',可在創(chuàng)建線程時使用參數(shù)name標記線程名剿牺。當開始了兩個子線程后企垦,由于三個線程并行,主線程也要繼續(xù)運行晒来,而執(zhí)行兩個start()方法的時間很短钞诡,所以打印的時間是0s。并且這里的輸出結(jié)果包含了線程結(jié)束語句'... completed'湃崩,說明主線程運行結(jié)束荧降,程序并沒有退出,而是要等子線程運行結(jié)束后再退出攒读。

如何使得主線程退出后子線程自動退出呢朵诫?只需要對子線程調(diào)用setDaemon方法,將子線程標記成守護線程薄扁,如下所示:

def main():
    thread1 = threading.Thread(target=do_something, args=('First task', 2))
    thread2 = threading.Thread(target=do_something, args=('Second task', 4))
    thread1.setDaemon(True)
    thread2.setDaemon(True)
    start_time = time.time()
    thread1.start()
    thread2.start()
    print('Last time: %fs' % (time.time() - start_time))

main()

我們再運行程序剪返,得到以下結(jié)果:

First task started
Second task started
Last time: 0.000235s

和我們預(yù)想的一致,主線程退出后邓梅,子線程也退出了脱盲,沒來得及打印'... completed'語句。

另外一個問題是如何將主線程阻塞震放,等子線程運行完成后再繼續(xù)主線程宾毒,這樣我們就可以獲得兩個線程并行運行的時間了。只需要對子線程調(diào)用join方法就可以將主線程阻塞,如下所示:

def main():
    thread1 = threading.Thread(target=do_something, args=('First task', 2))
    thread2 = threading.Thread(target=do_something, args=('Second task', 4))
    start_time = time.time()
    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()
    print('Last time: %fs' % (time.time() - start_time))

main()

運行結(jié)果如下:

First task started
Second task started
First task completed
Second task completed
Last time: 4.004622s

從結(jié)果可以看出诈铛,運行時間并不是串行的6s乙各,而是兩者中的大者,原因在前一章中提到了幢竹,當線程遇到IO操作或者time.sleep時耳峦,GIL會釋放,將執(zhí)行權(quán)留給其他線程焕毫。

通過繼承Thread類并重寫其run方法進行多線程編程

上面的方法適用于邏輯簡單明確的情況蹲坷,當代碼邏輯復(fù)雜時,最好使用這種方法邑飒,方便代碼維護循签。

如果你明白了上面的方法,只需要進行細微的改動即可疙咸,下面是一個例子:

import threading

class DoSomething(threading.Thread):
    def __init__(self, content, sec):
        super().__init__()
        self.content = content
        self.sec = sec
    def run(self):
        print('%s started' % self.content)
        time.sleep(self.sec)
        print('%s completed' % self.content)

def main():
    thread1 = DoSomething('First task', 2)
    thread2 = DoSomething('Second task', 4)
    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()

main()

可以看出县匠,threading.Thread類的start方法,實際上就是運行其run方法撒轮。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末乞旦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子题山,更是在濱河造成了極大的恐慌兰粉,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顶瞳,死亡現(xiàn)場離奇詭異玖姑,居然都是意外死亡,警方通過查閱死者的電腦和手機慨菱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門客峭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人抡柿,你說我怎么就攤上這事〉瓤郑” “怎么了洲劣?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長课蔬。 經(jīng)常有香客問我囱稽,道長,這世上最難降的妖魔是什么二跋? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任战惊,我火速辦了婚禮,結(jié)果婚禮上扎即,老公的妹妹穿的比我還像新娘吞获。我一直安慰自己况凉,他們只是感情好,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布各拷。 她就那樣靜靜地躺著刁绒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪烤黍。 梳的紋絲不亂的頭發(fā)上知市,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機與錄音速蕊,去河邊找鬼嫂丙。 笑死,一個胖子當著我的面吹牛规哲,可吹牛的內(nèi)容都是我干的跟啤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼媳叨,長吁一口氣:“原來是場噩夢啊……” “哼腥光!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起糊秆,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤武福,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后痘番,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捉片,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年汞舱,在試婚紗的時候發(fā)現(xiàn)自己被綠了伍纫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡昂芜,死狀恐怖莹规,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泌神,我是刑警寧澤良漱,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站欢际,受9級特大地震影響母市,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜损趋,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一患久、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦蒋失、人聲如沸返帕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽溉旋。三九已至,卻和暖如春嫉髓,著一層夾襖步出監(jiān)牢的瞬間观腊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工算行, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留梧油,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓州邢,卻偏偏與公主長得像儡陨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子量淌,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348