【python】多線程(基礎(chǔ)篇): join() 函數(shù)岖妄、is_alive()方法

線程

什么是線程

(1)線程是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位型将。
(2)它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位荐虐。
(3)一條線程指的是進(jìn)程中一個(gè)單一順序的控制流七兜,一個(gè)進(jìn)程中可以并發(fā)多個(gè)線程,每條線程并行執(zhí)行不同的任務(wù)福扬。
(4)一個(gè)線程是一個(gè)execution context(執(zhí)行上下文)腕铸,即一個(gè)cpu執(zhí)行時(shí)所需要的一串指令。

【重點(diǎn)】一個(gè)程序運(yùn)行后至少有一個(gè)進(jìn)程铛碑,一個(gè)進(jìn)程中可以包含多個(gè)線程狠裹;


線程的工作方式

CPU會(huì)給你一個(gè)在同一時(shí)間能夠做多個(gè)運(yùn)算的幻覺,實(shí)際上它在每個(gè)運(yùn)算上只花了極少的時(shí)間汽烦,本質(zhì)上CPU同一時(shí)刻只干了一件事涛菠。它能這樣做就是因?yàn)樗忻總€(gè)運(yùn)算的execution context。就像你能夠和你朋友共享同一本書一樣撇吞,多任務(wù)也能共享同一塊CPU俗冻。


啟動(dòng)多個(gè)線程(函數(shù)實(shí)現(xiàn))

Python提供了一個(gè)內(nèi)置模塊 threading.Thread,可以很方便地讓我們創(chuàng)建多線程牍颈。 threading.Thread() 一般接收兩個(gè)參數(shù):

  • 線程函數(shù)名:要放置線程讓其后臺(tái)執(zhí)行的函數(shù)迄薄,由我們自已定義,注意不要加()颂砸;

  • 線程函數(shù)的參數(shù):線程函數(shù)名所需的參數(shù)噪奄,以元組的形式傳入。若不需要參數(shù)人乓,可以不指定勤篮。

【舉個(gè)例子】:

import threading
import time
def run(n):
    print("task ",n )
    time.sleep(2)

# run("t1")
# run("t2")
t1 = threading.Thread(target=run,args=("t1",))#生成一個(gè)線程實(shí)例
t2 = threading.Thread(target=run,args=("t2",))
t1.start()
t2.start()

【輸出】:
task  t1
task  t2

【解釋】由于每個(gè)方法都有單獨(dú)的進(jìn)程,會(huì)同時(shí)開始執(zhí)行色罚,上面代碼會(huì)同時(shí)輸出


啟動(dòng)多個(gè)線程(類實(shí)現(xiàn))

相比較函數(shù)而言碰缔,使用類創(chuàng)建線程,會(huì)比較麻煩一點(diǎn)戳护。 首先金抡,我們要自定義一個(gè)類瀑焦,對(duì)于這個(gè)類有兩點(diǎn)要求:

  • 必須繼承 threading.Thread 這個(gè)父類;

  • 必須覆寫 run 方法梗肝。
    【看個(gè)實(shí)例】

# 類方法
class MYThread(threading.Thread):

    def __init__(self,n):
        super().__init__()
        self.n = n

    def run(self):
        print("task",self.n)
        time.sleep(2)
        print("{} finished\n".format(self.n))

t1 = MYThread('t1')
t2 = MYThread('t2')


t = time.time()
t1.start()
t2.start()

# 調(diào)用者會(huì)等待該線程結(jié)束后榛瓮,再執(zhí)行;

t2.join()

t1.join()

t1 = time.time()

print('main finished...')
print("線程所耗時(shí)間為:",t1 - t)

【輸出】

task t1
task t2
t1 finished
t2 finished


main finished...
線程所耗時(shí)間為: 2.0015668869018555
獲取線程的執(zhí)行結(jié)果
  • f1.result()
  • map()
  • as_completed
  • wait
  • add_done_callback

【關(guān)于 join() 函數(shù)】

import threading
import time
def run(n):
    print("task ",n )
    time.sleep(2)
    print("task done",n)

start_time = time.time()
for i in range(12):
    t = threading.Thread(target=run,args=("t-%s" %i ,))
    t.start()

print("----------all threads has finished...")
print("cost:",time.time() - start_time)

輸出:

task  t-0
task  t-1
task  t-2
task  t-3
task  t-4
task  t-5
task  t-6
task  t-7
task  t-8
task  t-9
task  t-10
task  t-11----------all threads has finished...
cost: 
0.001996278762817383
task donetask done t-2
 t-0
task done t-4task done task done t-3t-1

task done t-7
task done t-9task done 
task done task done t-8
t-5t-6

task donetask done  t-11
t-10

我們知道線程有 就緒巫击、阻塞禀晓、運(yùn)行三種基本狀態(tài)。

  1. 就緒狀態(tài)是指線程具備運(yùn)行的所有條件坝锰,邏輯上可以運(yùn)行粹懒,在等待處理機(jī);

  2. 運(yùn)行狀態(tài)是指線程占有處理機(jī)正在運(yùn)行顷级;

  3. 阻塞狀態(tài)是指線程在等待一個(gè)事件(如某個(gè)信號(hào)量)凫乖,邏輯上不可執(zhí)行。

線程狀態(tài)轉(zhuǎn)換

關(guān)于【多線程】的小程序

from threading import Thread
import os, time

#計(jì)算密集型任務(wù)
def work():
    res = 0
    for i in range(100000000):
        res *= i

if __name__ == "__main__":
    l = []
    print("本計(jì)算機(jī)是",os.cpu_count(),"核 CPU")
    start = time.time()
    for i in range(4):
        p = Thread(target=work)  # 多進(jìn)程
        l.append(p)
        p.start()
    for p in l:
        p.join()
    stop = time.time()
    print("本計(jì)算機(jī)計(jì)算密集型任務(wù)弓颈,多線程耗時(shí) %s" % (stop - start))

輸出:

本計(jì)算機(jī)是 8 核 CPU
本計(jì)算機(jī)計(jì)算密集型任務(wù)帽芽,多線程耗時(shí) 25.76108407974243

【關(guān)于is_alive()方法】:
可以用來判斷一個(gè)線程是否結(jié)束。

import threading
import time


def run(n):
    print("task ", n)
    time.sleep(2)
    print("task done", n)


start_time = time.time()
t_objs = []  # 存線程實(shí)例
for i in range(5):
    t = threading.Thread(target=run, args=("t-%s" % i,))
    t.start()
    t_objs.append(t)  # 為了不阻塞后面線程的啟動(dòng)翔冀,不在這里join嚣镜,先放到一個(gè)列表里

for t in t_objs:
    print(t.is_alive())

for t in t_objs:  # 循環(huán)線程實(shí)例列表,等待所有線程執(zhí)行完畢
    t.join()

for t in t_objs:
    print(t.is_alive())

print("----------all threads has finished...")
print("cost:", time.time() - start_time)

輸出:

task  t-0
task  t-1
task  t-2
task  t-3
task True
True
True
True
True
 t-4
task done task done t-1
t-0
task done t-4task done 
task done t-3t-2

False
False
False
False
False
----------all threads has finished...
cost: 2.0031514167785645

【續(xù)】:【python】多線程(高級(jí)篇):鎖 橘蜜、GIL(全局鎖)、Queue隊(duì)列以及線程池http://www.reibang.com/p/04af68ab2c9b

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末付呕,一起剝皮案震驚了整個(gè)濱河市计福,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌徽职,老刑警劉巖象颖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異姆钉,居然都是意外死亡说订,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門潮瓶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來陶冷,“玉大人,你說我怎么就攤上這事毯辅」÷祝” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵思恐,是天一觀的道長沾谜。 經(jīng)常有香客問我膊毁,道長,這世上最難降的妖魔是什么基跑? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任婚温,我火速辦了婚禮,結(jié)果婚禮上媳否,老公的妹妹穿的比我還像新娘栅螟。我一直安慰自己,他們只是感情好逆日,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布嵌巷。 她就那樣靜靜地躺著,像睡著了一般室抽。 火紅的嫁衣襯著肌膚如雪搪哪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天坪圾,我揣著相機(jī)與錄音晓折,去河邊找鬼。 笑死兽泄,一個(gè)胖子當(dāng)著我的面吹牛漓概,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播病梢,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼胃珍,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了蜓陌?” 一聲冷哼從身側(cè)響起觅彰,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钮热,沒想到半個(gè)月后填抬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡隧期,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年飒责,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仆潮。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宏蛉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鸵闪,到底是詐尸還是另有隱情檐晕,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站辟灰,受9級(jí)特大地震影響个榕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芥喇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一西采、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧继控,春花似錦械馆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至冶忱,卻和暖如春尾菇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背囚枪。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國打工派诬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像藤韵,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子棕兼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355