day 18 總結(jié)

day 18 多線程(thread)

Date:2019.5.9

內(nèi)容綱要:

線程.png

一、線程

import time
from datetime import datetime
import threading    # 專門提供和線程相關(guān)的操作

??每個(gè)進(jìn)程默認(rèn)都有一個(gè)線程,這個(gè)線程叫主線程; 其他的線程都叫子線程

def download(film_name):
    print('開始下載: %s' % film_name, datetime.now())
    time.sleep(5)
    print('%s下載完成' % film_name, datetime.now())

1.單線程下載兩個(gè)電影

??在一個(gè)線程中下載兩個(gè)電影:時(shí)間是兩個(gè)電影下載的總和

2.線程模塊

1)current_thread函數(shù) - 獲取當(dāng)前線程
print(threading.current_thread())
2) Thread類

??Thread類的對(duì)象就是線程,所以需要子線程就創(chuàng)建這個(gè)類的對(duì)象
Thread(target,args,kwargs)
target - 函數(shù), 需要在當(dāng)前創(chuàng)建的子線程中去調(diào)用的函數(shù)
args/kwargs - 調(diào)用target中的函數(shù)需要的實(shí)參列表

# a.創(chuàng)建線程對(duì)象
t1 = threading.Thread(target=download, args=('復(fù)聯(lián)5',))
# t1 = threading.Thread(target=download, kwargs={'film_name': '復(fù)聯(lián)5'})
t2 = threading.Thread(target=download, args=('007',))

# b.開始執(zhí)行子線程中的任務(wù): 線程對(duì)象.start()
"""
通過start方法,在子線程中去調(diào)用target對(duì)應(yīng)的函數(shù)
"""
t1.start()
t2.start()

二、線程的創(chuàng)建和使用

1.創(chuàng)建自己的線程類

1)聲明一個(gè)類繼承Thread
2)實(shí)現(xiàn)run方法,這個(gè)方法中的人物就是需要在子線程中執(zhí)行的任務(wù)
3)用子類直接創(chuàng)建線程對(duì)象
4)通過start去執(zhí)行子線程中的任務(wù)
??注意:一個(gè)進(jìn)程中如果有多個(gè)線程,程序會(huì)在所有的線程都結(jié)束的時(shí)候才結(jié)束,發(fā)生異常崩潰其實(shí)崩潰的是線程,

class DownloadThread(Thread):

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

    def run(self):
        # print(current_thread())
        # print('在子線程中執(zhí)行的代碼')
        print('開始下載:%s' % self.film_name, datetime.now())
        time.sleep(2)
        print('結(jié)束下載:%s' % self.film_name, datetime.now())


t1 = DownloadThread('哥斯拉2')
t2 = DownloadThread('大偵探皮卡丘')
t1.start()
t2.start()
# t1.run()        # 不能直接調(diào)用run方法,因?yàn)檫@樣調(diào)用不會(huì)在子線程中執(zhí)行任務(wù)

三、join

1.join

??如果希望某個(gè)任務(wù)是在某個(gè)線程結(jié)束后才執(zhí)行,那就將這個(gè)任務(wù)的帶放在對(duì)應(yīng)線程對(duì)象調(diào)用join方法的后面

class DownloadThread(Thread):

    def __init__(self, name, time):
        super().__init__()
        self.name = name
        self.time = time

    def run(self):
        print('開始下載:%s' % self.name, datetime.now())
        time.sleep(2)
        print('結(jié)束下載:%s' % self.name, datetime.now())


t1 = DownloadThread('沉默的羔羊', 5)
t2 = DownloadThread('權(quán)利的游戲', 7)


t2.start()



t2.join()
print('電影下載完成,用時(shí)%d秒')

t1.start()
t1.join()
print('電影下載完成,用時(shí)%d秒')

四、線程數(shù)據(jù)及鎖的使用

1.線程數(shù)據(jù)的混亂

??數(shù)據(jù)安全問題:當(dāng)多個(gè)線程同時(shí)對(duì)一個(gè)數(shù)據(jù)進(jìn)行讀寫操作的時(shí)候,可能會(huì)出現(xiàn)一個(gè)線程剛把數(shù)據(jù)讀出來還沒來的及寫進(jìn)去,另一個(gè)線程進(jìn)行讀操作而出現(xiàn)的

2.鎖的使用:數(shù)據(jù)混亂解決 - 加鎖

1)保證每個(gè)數(shù)據(jù)對(duì)應(yīng)一個(gè)鎖對(duì)象
2)操作數(shù)據(jù)前加鎖,數(shù)據(jù)操作完成后釋放鎖

class Acount(Thread):

    def __init__(self, name, tel, balance = 50):
        super().__init__()
        self.name = name
        self.tel = tel
        self.balance = balance
        # 關(guān)聯(lián)一個(gè)鎖對(duì)象
        self.lock = Lock()

    def save_money(self, money):
        print('開始存錢')
        # 加鎖
        self.lock.acquire()
        value = self.balance
        time.sleep(4)
        self.balance = value + money
        print('存錢成功!%.2f' % self.balance)
        # 釋放鎖
        self.lock.release()

    def draw_money(self, money):
        print('開始取錢')
        # 加鎖
        self.lock.acquire()
        value = self.balance
        time.sleep(4)
        if value < money:
            print('取錢失??!余額不足')
            return
        self.balance = value - money
        print('取錢成功:%.2f' % self.balance)
        # 釋放鎖
        self.lock.release()

acount = Acount('李卓然', '18648606874', 10000)

t1 = Thread(target=acount.save_money, args=(1000,))
t2 = Thread(target=acount.draw_money, args=(500,))

t1.start()
t2.start()


print('======================')
share_data = 1000
lock = Lock()


def add_data(value):
    lock.acquire()
    global share_data
    old_data = share_data
    time.sleep(4)
    share_data = old_data + value
    lock.release()
    print(value)


t1 = Thread(target=add_data, args=(200,))
t2 = Thread(target=add_data, args=(300,))

t1.start()
t2.start()
t1.join()
t2.join()

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

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