2018-09-13 day19 多線程

一.多線程技術(shù)

1.主線程:每個(gè)進(jìn)程默認(rèn)都會(huì)有一個(gè)線程,這個(gè)線程我們一般叫他主線程
默認(rèn)情況下,所有的代碼都是在主線程中執(zhí)行
2.子線程
一個(gè)線程中可以有多個(gè)線程,除了主線程以外,其他的線程需要手動(dòng)添加
3.threading是python中的內(nèi)置模塊,用來支持多線程
Thread類的對象就是線程對象,需要線程的時(shí)候,就創(chuàng)建這個(gè)類或者這個(gè)類的子類對象

import threading
import datetime
import time
def download(file):
    print("開始下載",datetime.datetime.now())
    time.sleep(5)
    print(file+"下載結(jié)束:",datetime.datetime.now())


# print("主線程中的代碼")
# #1.在線程中下載兩個(gè)電影
# download("速度與激情")
# download("沉默的羔羊")
print(threading.currentThread())

#2.在兩個(gè)子線程中去下載電影
"""
Thread(target,args)
target:需要在子線程中調(diào)用的函數(shù)的函數(shù)名
args:函數(shù)的實(shí)參
返回值:創(chuàng)建好的線程對象

"""
t1 = threading.Thread(target=download,args=("速度與激情",))

#開始執(zhí)行t1對應(yīng)的線程中的任務(wù)
t1.start()

t2 = threading.Thread(target=download,args=("哆啦A夢",))
#想要在子線程中執(zhí)行任務(wù),必須通過線程對象調(diào)用start方法才行
t2.start()
print("==========")
輸出:
<_MainThread(MainThread, started 5544)>
開始下載 2018-09-13 17:27:55.494570
開始下載 2018-09-13 17:27:55.495571
==========
速度與激情下載結(jié)束: 2018-09-13 17:28:00.494856
哆啦A夢下載結(jié)束: 2018-09-13 17:28:00.495857

二.面向?qū)ο蟮亩嗑€程技術(shù)

1.聲明一個(gè)類,繼承自Thread類
2.重寫run方法,將需要在子線程中執(zhí)行的任務(wù)放到run方法中
3.在需要子線程的位置去創(chuàng)建這個(gè)類的對象,然后用對象調(diào)用start方法

from threading import Thread
import datetime
import time
from random import randint
class DownloadThread(Thread):
    def __init__(self,file):
        super().__init__()
        self.file = file

    def run(self):
        print(self.file+"開始下載:",datetime.datetime.now())
        time.sleep(randint(5,10))
        print(self.file+"下載結(jié)束:",datetime.datetime.now())
print("======")
t1 = DownloadThread("水形物語")
t1.start()
print("++++++")
輸出:
水形物語開始下載: 2018-09-13 17:32:06.642935
++++++
水形物語下載結(jié)束: 2018-09-13 17:32:11.643221

3.join的方法的使用

from threading import Thread
import time
from datetime import datetime
from random import randint
#在兩個(gè)子線程中下載兩個(gè)電影,在主線程中統(tǒng)計(jì)兩個(gè)電影下載的總的時(shí)間
#如果希望兩個(gè)線程結(jié)束后才執(zhí)行某個(gè)操作,就用那個(gè)線程調(diào)用join方法
class DownloadThread(Thread):
    def __init__(self,file):
        super().__init__()
        self.file = file
    def run(self):
        print(self.file+"開始下載:",datetime.now())
        time.sleep(randint(5,15))
        print(self.file+"下載結(jié)束:",datetime.now())
t1 = DownloadThread("鋼鐵俠")
t2 = DownloadThread("金剛狼")
start = time.time()

tim1 = t1.start()
tim2 = t2.start()

#系統(tǒng)t1和t2中的代碼都結(jié)束后才執(zhí)行下面的代碼
t1.join()   #這句代碼在t1的線程結(jié)束后才執(zhí)行
t2.join()
end = time.time()
print(end-start)
輸出:
鋼鐵俠開始下載: 2018-09-13 17:34:31.197203
金剛狼開始下載: 2018-09-13 17:34:31.197203
鋼鐵俠下載結(jié)束: 2018-09-13 17:34:38.197604
金剛狼下載結(jié)束: 2018-09-13 17:34:43.197890
12.001686573028564

4.線程間的數(shù)據(jù)共享

模擬多個(gè)人對同一個(gè)賬號進(jìn)行操作
同步鎖(RLock)和互斥鎖(Lock)

import time
from threading import Thread,Lock,RLock
class Account:
    """賬號類"""
    def __init__(self,balance):
        #余額
        self.balance = balance
        #創(chuàng)建鎖對象
        self.lock = Lock()


    #存錢的過程:讀出原來的余額,確定錢的一系列操作,
    # 將原來的余額加上存的數(shù)額,產(chǎn)生最新的余額再保存
    def save_money(self,amount):
        print("開始存錢")
        #加鎖
        self.lock.acquire()
        #獲取原來的余額
        old_amount = self.balance
        #模擬時(shí)間消耗
        time.sleep(5)
        #修改余額
        self.balance = old_amount + amount
        print("存錢成功,余額:",self.balance)

        #解鎖
        self.lock.release()

        #取錢
    def get_money(self,amount):
        print("開始取錢")
        self.lock.acquire()
        old_amount = self.balance
        if old_amount < amount:
            print("余額不足!")
            return
        time.sleep(5)
        self.balance = old_amount - amount
        print("取錢成功,余額:",self.balance)
        self.lock.release()
    def show_balance(self):
        print("當(dāng)前余額為:",self.balance)

#創(chuàng)建賬號
account = Account(1000)
# account.save_money(200)
# account.get_money(100)
"""
當(dāng)多個(gè)線程同時(shí)對一個(gè)數(shù)據(jù)進(jìn)行操作的時(shí)候,可能會(huì)出現(xiàn)數(shù)據(jù)混亂的問題
"""

t1 = Thread(target=account.save_money,args=(200,))
t2 = Thread(target=account.save_money,args=(1300,))
t3 = Thread(target=account.get_money,args=(800,))
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
account.show_balance()
輸出:
當(dāng)前余額為: 1000
開始存錢
開始存錢
開始取錢
存錢成功,余額: 1200
存錢成功,余額: 2500
取錢成功,余額: 1700
當(dāng)前余額為: 1700

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 進(jìn)程:正在運(yùn)行的一個(gè)程序,每個(gè)進(jìn)程相互獨(dú)立,并且運(yùn)行在其專用且受保護(hù)的內(nèi)存空間里面的。 線程:一個(gè)進(jìn)程要想執(zhí)行任務(wù)...
    Deathfeeling閱讀 208評論 2 1
  • 進(jìn)程 1.什么是進(jìn)程:在系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序2.每個(gè)進(jìn)程之間是獨(dú)立的,每個(gè)進(jìn)程均運(yùn)行在其專用且受保護(hù)的內(nèi)存...
    xaidc閱讀 189評論 0 0
  • 一、多線程技術(shù) 1,主線程 每個(gè)進(jìn)程默認(rèn)都會(huì)有一個(gè)線程,這個(gè)線程我們一般叫他主線程默認(rèn)情況下,所有的代碼都是在主線...
    fanzl閱讀 200評論 0 0
  • 舊城區(qū)的一處院落里,旺盛生長著一株南瓜苗,它粗壯的藤蔓攀上院子?xùn)|南角的老墻,十余朵金黃色的南瓜花上有一兩只蜜蜂在傳...
    手寫晴閱讀 911評論 2 6
  • 心態(tài)決定一切吧!這幾天和老大對抗上了,總覺得自己在和孩子斤斤計(jì)較了。十幾歲的孩子我想應(yīng)該是最需要媽媽的信任吧,而我...
    向著陽光00閱讀 222評論 0 0

友情鏈接更多精彩內(nèi)容