2018-09-13 Day19-多線程基礎(chǔ)

  • 進(jìn)程:正在運(yùn)行的一個(gè)程序府适,每個(gè)進(jìn)程相互獨(dú)立唯绍,并且運(yùn)行在其專用且受保護(hù)的內(nèi)存空間里面的。

  • 線程:一個(gè)進(jìn)程要想執(zhí)行任務(wù)偿荷,必須得有線程(每個(gè)進(jìn)程至少有一個(gè)線程)窘游,一個(gè)進(jìn)程所有任務(wù)都在線程中執(zhí)行。

  • 主線程:每個(gè)進(jìn)程默認(rèn)有一個(gè)線程跳纳,這個(gè)線程叫主線程忍饰。默認(rèn)情況下,所有的代碼都是在主線程中執(zhí)行的寺庄。

  • 子線程:一個(gè)進(jìn)程可以有多個(gè)線程艾蓝。除了主線程以外,其他線程需要手動(dòng)添加斗塘。

多線程原理:
同一時(shí)間赢织,CPU只能處理一條線程,只有1條線程在工作馍盟。多線程并發(fā)執(zhí)行于置,其實(shí)就是CPU快速的在多線程之間調(diào)度(切換),當(dāng)CPU調(diào)度線程的時(shí)間足夠快贞岭,就造成了多線程并發(fā)執(zhí)行的假象八毯。

使用情況:
讓多個(gè)任務(wù)同時(shí)執(zhí)行搓侄。

補(bǔ)充:
a、打印當(dāng)前時(shí)間

import datetime
datetime.datetime.now()

b宪彩、延時(shí)

import time
time.sleep(s)

方式一

1休讳、模塊

python中內(nèi)置模塊 threading,用來支持多線程尿孔。Thread類的對(duì)象就是線程對(duì)象,需要線程的時(shí)候筹麸,就創(chuàng)建這個(gè)類或者這個(gè)類的子類對(duì)象活合。

import threading

獲取當(dāng)前線程對(duì)象 >>> 用于測試

threading.current_thread()
2、創(chuàng)建子線程對(duì)象
t1 = threading.Thread(target=download, args=('終結(jié)者',))
"""
target:需要在子線程中調(diào)用的函數(shù)的函數(shù)名物赶,子線程中執(zhí)行的任務(wù)就是函數(shù)里面的代碼白指。
args:函數(shù)對(duì)應(yīng)的參數(shù)值(元組)
返回值:創(chuàng)建好的線程對(duì)象
"""
3、執(zhí)行
t1.start()

效果:

import threading
import datetime
import time

#模擬下載兩個(gè)電影
def download(file):
    print('開始下載:', datetime.datetime.now())
    # 線程阻塞2s
    time.sleep(2)
    print(file+'下載結(jié)束',datetime.datetime.now())
    print(threading.current_thread())
t1 = threading.Thread(target=download, args=('終結(jié)者2',))
t1.start()
t2 = threading.Thread(target=download, args=('沉默的羔羊',))
t2.start()
download('終結(jié)者1')

開始下載: 2018-09-13 11:08:56.927703
開始下載: 2018-09-13 11:08:56.928703
開始下載: 2018-09-13 11:08:56.928703
終結(jié)者2下載結(jié)束 2018-09-13 11:08:58.927818
<Thread(Thread-1, started 2324)>
沉默的羔羊下載結(jié)束 2018-09-13 11:08:58.928818
<Thread(Thread-2, started 5908)>
終結(jié)者1下載結(jié)束 2018-09-13 11:08:58.928818
<_MainThread(MainThread, started 5852)>

方式二---面向?qū)ο蟮亩嗑€程技術(shù)(重點(diǎn))

1酵紫、聲明一個(gè)類繼承自Thread類
2告嘲、重寫run方法,將需要在子線程中執(zhí)行的任務(wù)放到run方法中
3奖地、在需要子線程的位置去創(chuàng)建這個(gè)類的對(duì)象橄唬,然后調(diào)用start 方法去執(zhí)行run中的任務(wù)。
from threading import Thread
import datetime
import time

class DownLoadThread(Thread):
    def __init__(self, file):
        super().__init__()
        self.file = file

    def run(self):
        print('開始下載:<%s>  時(shí)間:%s'%(self.file,datetime.datetime.now()))
        time.sleep(5)
        print('下載結(jié)束:<%s>参歹!  時(shí)間:%s'%(self.file,datetime.datetime.now()))

print('===========')

t1 = DownLoadThread('沉默的羔羊')
t1.start()

print('+++++++++++')

結(jié)果:
===========
開始下載:<沉默的羔羊>  時(shí)間:2018-09-13 11:26:42.730664
+++++++++++
下載結(jié)束:<沉默的羔羊>仰楚!  時(shí)間:2018-09-13 11:26:47.730950

三、join方法的使用

如果希望某個(gè)線程結(jié)束后才執(zhí)行某個(gè)操作犬庇,就用線程對(duì)象調(diào)用 join()

start()會(huì)自動(dòng)調(diào)用run()

from threading import Thread
import time
import datetime
import random

class DownLoadThread(Thread):
    def __init__(self, file):
        super().__init__()
        self.file = file

    def run(self):
        print(self.file+' 開始下載', datetime.datetime.now())
        time.sleep(random.randint(5,15))
        print(self.file+' 下載結(jié)束', datetime.datetime.now())


t1 = DownLoadThread('美麗人生')
t2 = DownLoadThread('怦然心動(dòng)')

start = time.time()

t1.start()
t2.start()

#t1,t2都結(jié)束才執(zhí)行
t1.join()   #后面的代碼在t1對(duì)應(yīng)的線程結(jié)束后才執(zhí)行
t2.join()   #后面的代碼在t1對(duì)應(yīng)的線程結(jié)束后才執(zhí)行
end = time.time()
print(end - start)

結(jié)果:
美麗人生 開始下載 2018-09-13 13:36:42.334387
怦然心動(dòng) 開始下載 2018-09-13 13:36:42.334387
美麗人生 下載結(jié)束 2018-09-13 13:36:49.334787
怦然心動(dòng) 下載結(jié)束 2018-09-13 13:36:50.336844
8.00445818901062

四僧界、多線程的數(shù)據(jù)混亂問題

盡量避免多個(gè)線程對(duì)同一個(gè)數(shù)據(jù)進(jìn)行操作

解決方法:對(duì)相關(guān)代碼加鎖,讓同一時(shí)間只有能有一個(gè)線程進(jìn)行操作臭挽,釋放后捂襟,才能讓其它線程操作

鎖: 同步鎖(RLock) 和 互斥鎖(Lock)-- 了解

from threading import Lock
1、創(chuàng)建鎖對(duì)象
self.lock = Lock()
# 一般寫在__init__方法中
2欢峰、加鎖
self.lock.acquire()
# 線程操作前
3葬荷、解鎖
self.lock.release()
#  線程操作后

實(shí)例:

"""__author__=Deathfeeling"""
import time
from threading import Thread, Lock


class Account():
    """賬號(hào)類"""
    def __init__(self, balance):
        self.balance = balance
        # 創(chuàng)建鎖對(duì)象
        self.lock = Lock()

    def save_money(self, amount):
        """存錢"""
        print('開始存錢')

        # 加鎖
        self.lock.acquire()
        old_amount = self.balance
        time.sleep(2)
        self.balance = old_amount + amount
        print('存錢成功!最新余額是:',self.balance)

        # 解鎖
        self.lock.release()

    def get_money(self, amount):
        """取錢"""
        self.lock.acquire()
        print('開始取錢')
        old_amount = self.balance
        if old_amount < amount:
            print('余額不足')
            return
        time.sleep(2)
        self.balance = old_amount - amount
        print('取錢成功赤赊!最新余額是:', self.balance)
        self.lock.release()

    def show_balance(self):
        print('當(dāng)前余額:', self.balance)


account = Account(1000)
# account.save_money(200)
# account.get_money(100)
# account.show_balance()
t1 = Thread(target=account.save_money, args=(200,))
t2 = Thread(target=account.save_money, args=(300,))
t1.start()
t2.start()

結(jié)果:
開始存錢
開始存錢
存錢成功闯狱!最新余額是: 1200
存錢成功!最新余額是: 1500
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抛计,一起剝皮案震驚了整個(gè)濱河市哄孤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吹截,老刑警劉巖瘦陈,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凝危,死亡現(xiàn)場離奇詭異,居然都是意外死亡晨逝,警方通過查閱死者的電腦和手機(jī)蛾默,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捉貌,“玉大人支鸡,你說我怎么就攤上這事〕们裕” “怎么了牧挣?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長醒陆。 經(jīng)常有香客問我瀑构,道長,這世上最難降的妖魔是什么刨摩? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任寺晌,我火速辦了婚禮,結(jié)果婚禮上澡刹,老公的妹妹穿的比我還像新娘呻征。我一直安慰自己,他們只是感情好像屋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布怕犁。 她就那樣靜靜地躺著,像睡著了一般己莺。 火紅的嫁衣襯著肌膚如雪奏甫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天凌受,我揣著相機(jī)與錄音阵子,去河邊找鬼。 笑死胜蛉,一個(gè)胖子當(dāng)著我的面吹牛挠进,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播誊册,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼领突,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了案怯?” 一聲冷哼從身側(cè)響起君旦,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后金砍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體局蚀,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年恕稠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了琅绅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鹅巍,死狀恐怖千扶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情昆著,我是刑警寧澤县貌,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站凑懂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏梧宫。R本人自食惡果不足惜接谨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望塘匣。 院中可真熱鬧脓豪,春花似錦、人聲如沸忌卤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽驰徊。三九已至笤闯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間棍厂,已是汗流浹背颗味。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留牺弹,地道東北人浦马。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像张漂,于是被迫代替她去往敵國和親晶默。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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

  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對(duì)應(yīng)一個(gè)進(jìn)程,當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行時(shí),即變成一個(gè)進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    勝浩_ae28閱讀 5,106評(píng)論 0 23
  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對(duì)應(yīng)一個(gè)進(jìn)程,當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行時(shí),即變成一個(gè)進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    小徐andorid閱讀 2,807評(píng)論 3 53
  • 本文是我自己在秋招復(fù)習(xí)時(shí)的讀書筆記航攒,整理的知識(shí)點(diǎn)磺陡,也是為了防止忘記,尊重勞動(dòng)成果,轉(zhuǎn)載注明出處哦仅政!如果你也喜歡垢油,那...
    波波波先森閱讀 11,257評(píng)論 4 56
  • ??一個(gè)任務(wù)通常就是一個(gè)程序,每個(gè)運(yùn)行中的程序就是一個(gè)進(jìn)程圆丹。當(dāng)一個(gè)程序運(yùn)行時(shí)滩愁,內(nèi)部可能包含了多個(gè)順序執(zhí)行流,每個(gè)順...
    OmaiMoon閱讀 1,668評(píng)論 0 12
  • 【讓孩子成才秘密 】讀書分享打卡 ? 讀書使命: 為家族昌盛而讀書辫封! 為家庭幸福而讀書硝枉! 時(shí)間:2018.6.2 ...
    王麗_0853閱讀 122評(píng)論 0 0