Python學(xué)習(xí)總結(jié)之六 多線程

一.線程的概念

概念:
在一個(gè)進(jìn)程的內(nèi)部养距,要同時(shí)干多件事棍厌,就需要同時(shí)運(yùn)行多個(gè)“子任務(wù)”,我們把進(jìn)程內(nèi)的這些“子任務(wù)”叫做線程敬肚。

線程通常叫做輕型的進(jìn)程艳馒。線程是共享內(nèi)存空間的并發(fā)執(zhí)行的多任務(wù),每一個(gè)線程都共享一個(gè)進(jìn)程的資源第美。

線程是最小的執(zhí)行單元什往,而進(jìn)程由至少一個(gè)線程組成,這些線程的運(yùn)行順序是不確定的慌闭、隨機(jī)的贡必、不可預(yù)測的仔拟。

模塊:
1飒赃、_thread模塊 低級(jí)模塊
2载佳、threading模塊 高級(jí)模塊,對_thread進(jìn)行了封裝

二.啟動(dòng)線程

在線程里面setDaemon()和join()方法都是常用的挠乳,他們的區(qū)別如下

  1. join ()方法:主線程A中睡扬,創(chuàng)建了子線程B卖怜,并且在主線程A中調(diào)用了B.join()阐枣,那么,主線程A會(huì)在調(diào)用的地方等待甩鳄,直到子線程B完成操作后娩贷, 才可以接著往下執(zhí)行锁孟,那么在調(diào)用這個(gè)線程時(shí)可以使用被調(diào)用線程的join方法。join([timeout]) 里面的參數(shù)時(shí)可選的储笑,代表線程運(yùn)行的最大時(shí)間突倍,即如果超過這個(gè)時(shí)間,不管這個(gè)此線程有沒有執(zhí)行完畢都會(huì)被回收焊虏,然后主線程或函數(shù)都會(huì)接著執(zhí)行的诵闭,如果線程執(zhí)行時(shí)間小于參數(shù)表示的 時(shí)間澎嚣,則接著執(zhí)行易桃,不用一定要等待到參數(shù)表示的時(shí)間。

  2. setDaemon()方法敌呈。主線程A中驱富,創(chuàng)建了子線程B匹舞,并且在主線程A中調(diào)用了B.setDaemon(),這個(gè)的意思是赐稽,把主線程A設(shè)置為守護(hù)線程,這時(shí)候晰绎,要是主線程A執(zhí)行結(jié)束了荞下,就不管子線程B是否完成,一并和主線程A退出.這就是setDaemon方法的含義,這基本和join是相反的仰税。此外陨簇,還有個(gè)要特別注意的:必須在start()方法調(diào)用之前設(shè)置迹淌,如果不設(shè)置為守護(hù)線程,程序會(huì)被無限掛起唉窃,只有等待了所有線程結(jié)束它才結(jié)束纹份。

import threading,time


def run(num):
    print("子線程(%s)開始" % (threading.current_thread().name))

    #實(shí)現(xiàn)線程的功能
    time.sleep(2)
    print("打印", num)
    time.sleep(2)

    print("子線程(%s)結(jié)束" % (threading.current_thread().name))

if __name__ == "__main__":
    #任何進(jìn)程默認(rèn)就會(huì)啟動(dòng)一個(gè)線程矮嫉,稱為主線程牍疏,主線程可以啟動(dòng)新的子線程
    #current_thread():返回返回當(dāng)前線程的實(shí)例
    print("主線程(%s)啟動(dòng)" % (threading.current_thread().name))

    #創(chuàng)建子線程                     線程的名稱
    t = threading.Thread(target=run, name="runThread", args=(1,))
    t.start()
    #t.setDaemon(True)#設(shè)置為后臺(tái)線程鳞陨,這里默認(rèn)是Fal#se,設(shè)置為True之后則主線程不用等待子線程
    #等待線程結(jié)束
    t.join()

    print("主線程(%s)結(jié)束" % (threading.current_thread().name))

三.多線程共享數(shù)據(jù).

多線程和多進(jìn)程最大的不同在于援岩,多進(jìn)程中掏导,同一個(gè)變量趟咆,各自有一份拷貝存在每個(gè)進(jìn)程中,互不影響鳞贷。而多線程中虐唠,所有變量都由所有線程共享。所以搓幌,任何一個(gè)變量都可以被任意一個(gè)線程修改眷蚓,因此,線程之間共享數(shù)據(jù)最大的危險(xiǎn)在于多個(gè)線程同時(shí)修改一個(gè)變量叉钥,容易把內(nèi)容改亂了投队。

3.1造成數(shù)據(jù)混亂.
import threading
num = 0

def run(n):
    global num
    for i in range(10000000):
        num = num + n    
        num = num - n    

if __name__ == "__main__":
    t1 = threading.Thread(target=run, args=(6,))
    t2 = threading.Thread(target=run, args=(9,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

    print("num =",num)

3.2線程鎖解決數(shù)據(jù)混亂.
#鎖對象
lock = threading.Lock()

num = 0
def run(n):
    global num

    for i in range(10000000):
        # 鎖
        # 確保了這段代碼只能由一個(gè)線程從頭到尾的完整執(zhí)行
        # 阻止了多線程的并發(fā)執(zhí)行敷鸦,包含鎖的某段代碼實(shí)際上只能以單線程模式執(zhí)行寝贡,所以效率大大滴降低了
        # 由于可以存在多個(gè)鎖,不同線程持有不同的鎖碟案,并試圖獲取其他的鎖价说,可能造成死鎖风秤,導(dǎo)致多個(gè)線程掛起。只能靠操作系統(tǒng)強(qiáng)制終止
        '''
        lock.acquire()
        try:
            num = num + n    #  15 = 9 + 6
            num = num - n    #  9
        finally:
            #修改完一定要釋放鎖
            lock.release()
        '''

        #與上面代碼功能相同领迈,with lock可以自動(dòng)上鎖與解鎖
        with lock:
            num = num + n
            num = num - n

if __name__ == "__main__":
    t1 = threading.Thread(target=run, args=(6,))
    t2 = threading.Thread(target=run, args=(9,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print("num =",num)
3.3 ThreadLocal

ThreadLocal 主要用來為各個(gè)線程管理其內(nèi)部數(shù)據(jù),它本身是一個(gè)全局變量惦费,但是每個(gè)線程卻可以利用它來保存屬于自己的私有數(shù)據(jù)薪贫,這些私有數(shù)據(jù)對其他線程也是不可見的刻恭。

import threading

num = 0
#創(chuàng)建一個(gè)全局的ThreadLocal對象
#每個(gè)線程有獨(dú)立的存儲(chǔ)空間
#每個(gè)線程對ThreadLocal對象都可以讀寫,但是互不影響
local = threading.local()

def run(x, n):
    x = x + n
    x = x - n

def func(n):
    #每個(gè)線程都有l(wèi)ocal.x交洗,就是線程的局部變量
    local.x = num
    for i in range(1000000):
        run(local.x, n)
    print("%s-%d"%(threading.current_thread().name, local.x))

if __name__ == "__main__":
    t1 = threading.Thread(target=func, args=(6,))
    t2 = threading.Thread(target=func, args=(9,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

    print("num =",num)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末构拳,一起剝皮案震驚了整個(gè)濱河市梁棠,隨后出現(xiàn)的幾起案子符糊,更是在濱河造成了極大的恐慌突那,老刑警劉巖计寇,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洁桌,死亡現(xiàn)場離奇詭異荤牍,居然都是意外死亡啰脚,警方通過查閱死者的電腦和手機(jī)拣播,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進(jìn)店門收擦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來塞赂,“玉大人宴猾,你說我怎么就攤上這事叼旋。” “怎么了讹剔?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵陌兑,是天一觀的道長。 經(jīng)常有香客問我兔综,道長软驰,這世上最難降的妖魔是什么碌宴? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任贰镣,我火速辦了婚禮碑隆,結(jié)果婚禮上蹬音,老公的妹妹穿的比我還像新娘著淆。我一直安慰自己,他們只是感情好独泞,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布懦砂。 她就那樣靜靜地躺著荞膘,像睡著了一般玉工。 火紅的嫁衣襯著肌膚如雪羽资。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天遵班,我揣著相機(jī)與錄音屠升,去河邊找鬼瞄勾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛弥激,可吹牛的內(nèi)容都是我干的进陡。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼微服,長吁一口氣:“原來是場噩夢啊……” “哼趾疚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起以蕴,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤糙麦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后丛肮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體焚廊,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袒餐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年墓懂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宛徊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片暖呕。...
    茶點(diǎn)故事閱讀 40,742評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖贷帮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锄禽,我是刑警寧澤,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布坝疼,位于F島的核電站,受9級(jí)特大地震影響耕陷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嗜诀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一拂蝎、第九天 我趴在偏房一處隱蔽的房頂上張望玄货。 院中可真熱鬧,春花似錦惩坑、人聲如沸蔓钟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽畅蹂。三九已至累贤,卻和暖如春检疫,著一層夾襖步出監(jiān)牢的瞬間夺溢,已是汗流浹背状勤。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓面哥,卻偏偏與公主長得像吱涉,于是被迫代替她去往敵國和親鳖链。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 一文讀懂Python多線程 1皮壁、線程和進(jìn)程 計(jì)算機(jī)的核心是CPU畏腕,它承擔(dān)了所有的計(jì)算任務(wù)铭污。它就像一座工廠磅网,時(shí)刻在運(yùn)...
    星丶雲(yún)閱讀 1,458評論 0 4
  • 1扼倘、線程和進(jìn)程 計(jì)算機(jī)的核心是CPU,它承擔(dān)了所有的計(jì)算任務(wù)绿语。它就像一座工廠匹耕,時(shí)刻在運(yùn)行既鞠。 假定工廠的電力有限洒敏,一...
    文哥的學(xué)習(xí)日記閱讀 14,361評論 0 9
  • 1、線程和進(jìn)程 計(jì)算機(jī)的核心是CPU踊谋,它承擔(dān)了所有的計(jì)算任務(wù)。它就像一座工廠,時(shí)刻在運(yùn)行。 假定工廠的電力有限亥揖,一...
    Andone1cc閱讀 494評論 0 1
  • 線程和進(jìn)程 計(jì)算機(jī)挚歧,用于計(jì)算的機(jī)器。計(jì)算機(jī)的核心是CPU橙困,在現(xiàn)在多核心的電腦很常見了。為了充分利用cpu核心做計(jì)算...
    人世間閱讀 24,348評論 3 85
  • 這兩招的人都很多,就是說HR會(huì)把你從其他崗弄到這倆崗槽华,比如你投環(huán)境只招45人 參考 制造類
    鴨梨山大哎閱讀 3,121評論 0 2