day19 總結(jié) - 多線程技術(shù)

01.recode

一個(gè)進(jìn)程默認(rèn)有一個(gè)線程确镊,這個(gè)線程叫主線程剑刑。默認(rèn)情況下脚曾,所有的代碼都是在主線程中執(zhí)行的

import time, datetime


def download(film_name):
    print('開始下載:%s' % film_name, datetime.datetime.now())
    time.sleep(5)   # 程序執(zhí)行到這個(gè)地方镣煮,線程會(huì)阻塞5秒(停5秒)安券,再執(zhí)行后面的代碼
    print('%s下載結(jié)束' % film_name, datetime.datetime.now())


if __name__ == '__main__':
    # 在主線程中下載兩個(gè)電影
    download('小黃人')
    download('地心游記')

開始下載:小黃人 2018-11-29 17:27:40.037304
小黃人下載結(jié)束 2018-11-29 17:27:45.037590
開始下載:地心游記 2018-11-29 17:27:45.037590
地心游記下載結(jié)束 2018-11-29 17:27:50.037876


02.多線程1

python中提供了threading模塊,來(lái)支持多線程技術(shù)

默認(rèn)創(chuàng)建的線程叫主線程昧绣,其他的線程叫子線程规肴。如果希望代碼在子線程中執(zhí)行,必須手動(dòng)創(chuàng)建線程對(duì)象

import threading
import time, datetime


def download(film_name):
    print('開始下載:%s' % film_name, datetime.datetime.now())
    time.sleep(5)   # 程序執(zhí)行到這個(gè)地方夜畴,線程會(huì)阻塞5秒(停5秒)拖刃,再執(zhí)行后面的代碼
    print('%s下載結(jié)束' % film_name, datetime.datetime.now())
    print('下載%s:'%film_name,threading.current_thread())

開始下載:小黃人 2018-11-29 17:31:54.387852
開始下載:地心游記 2018-11-29 17:31:54.388852
地心游記下載結(jié)束 2018-11-29 17:31:59.389138
下載地心游記: <Thread(Thread-2, started 7656)>
小黃人下載結(jié)束 2018-11-29 17:31:59.389138
下載小黃人: <Thread(Thread-1, started 7280)>


03.練習(xí)

import requests
from threading import Thread


def download(url: str):
    """下載函數(shù)"""
    image_data = requests.get(url).content
    file_name = url.split('/')[-1]
    with open('images/'+file_name, 'wb') as f:
        f.write(image_data)


# 1.下載接口對(duì)應(yīng)的數(shù)據(jù)
# url = 'https://www.apiopen.top/satinApi?type=1&page=1'
# data_dict = requests.get(url).json()
# datas = data_dict['data']
# for dict1 in datas:
#     # 拿到一個(gè)圖片地址,就為它創(chuàng)建一個(gè)線程對(duì)象贪绘,用來(lái)在子線程中下載這張圖片
#     t = Thread(target=download, args=(dict1['profile_image'],))
#     t.start()
#
# print('下載完成')


# 使用正則獲取數(shù)據(jù)
import re
url = 'https://www.apiopen.top/satinApi?type=1&page=1'
text = requests.get(url).text

all_profile_image = re.findall(r'"profile_image":"(.+?)",', text)
for image_url in all_profile_image:
    Thread(target=download, args=(image_url,)).start()

04.線程類的子類

from threading import Thread, current_thread

創(chuàng)建子線程兑牡,除了直接創(chuàng)建Thread的對(duì)象,還可以創(chuàng)建這個(gè)類的子類對(duì)象

注意:一個(gè)進(jìn)程中有多個(gè)線程税灌,進(jìn)程會(huì)在所有的線程都結(jié)束才會(huì)結(jié)束;線程中的任務(wù)執(zhí)行完了均函,線程就結(jié)束

# 1.聲明一個(gè)類繼承Thread
class DownloadThread(Thread):
    # 想要給run方法傳遞數(shù)據(jù)亿虽,通過(guò)添加對(duì)象屬性來(lái)傳
    def __init__(self, file_name):
        super().__init__()
        self.file_name = file_name

    # 2.重寫run方法
    def run(self):
        # 這個(gè)方法中的代碼會(huì)在子線程中執(zhí)行
        print('開始下載: %s' % self.file_name)


# 3.創(chuàng)建線程對(duì)象
t1 = DownloadThread('小黃人')
# 4.通過(guò)線程對(duì)象調(diào)用start在子線程中執(zhí)行run方法
t1.start()
# t1.run()   # 直接調(diào)用run方法,會(huì)在主線程中執(zhí)行

開始下載: 小黃人


05.join函數(shù)

from threading import Thread
import time,datetime,random

線程對(duì)象.join() - 等待線程對(duì)象中的任務(wù)執(zhí)行完成

class Download(Thread):
    def __init__(self, film_name):
        super().__init__()
        self.film_name = film_name

    def run(self):
        print('開始下載:%s' % self.film_name)
        a = random.randint(5, 12)
        time.sleep(a)
        print('%s開始結(jié)束' % self.film_name, '耗時(shí)%d秒' % a)


if __name__ == '__main__':
    t1 = Download('小黃人')
    t2 = Download('地心游記')
    time1 = time.time()
    t1.start()
    t2.start()

    # t1和t2中的任務(wù)都執(zhí)行完成后才執(zhí)行后面的代碼
    t1.join()
    t2.join()

    time2 = time.time()
    print('總共時(shí)間:', time2 - time1)

開始下載:小黃人
開始下載:地心游記
小黃人開始結(jié)束 耗時(shí)9秒
地心游記開始結(jié)束 耗時(shí)9秒
總共時(shí)間: 9.001514673233032


06.數(shù)據(jù)共享

import time, threading

注意:當(dāng)多個(gè)線程同時(shí)對(duì)同一個(gè)數(shù)據(jù)進(jìn)行操作的時(shí)候苞也,可能會(huì)出現(xiàn)數(shù)據(jù)混亂

多個(gè)線程對(duì)一個(gè)數(shù)據(jù)進(jìn)行操作洛勉,一個(gè)線程將數(shù)據(jù)讀出來(lái),還沒來(lái)得及存進(jìn)去如迟;
另一個(gè)線程又去讀了占键,這個(gè)時(shí)候就可能產(chǎn)生數(shù)據(jù)安全隱患 - 解決問(wèn)題的方案就是加鎖

Thread - 線程類(創(chuàng)建子線程)
Lock - 鎖(創(chuàng)建鎖對(duì)象)

class Account(object):
    def __init__(self, balance, name):
        self.balance = balance   # 余額
        self.name = name
        self.lock = threading.Lock()   # 創(chuàng)建鎖對(duì)象

    def save(self, num):
        """存錢"""
        print('開始存錢')
        # 加鎖
        self.lock.acquire()
        old_balance = self.balance
        time.sleep(5)
        self.balance = old_balance + num
        print('存錢成功癣籽!')
        # 解鎖
        self.lock.release()

    def draw(self, num):
        """取錢"""
        # 加鎖
        print('開始取錢!')
        self.lock.acquire()
        old_balance = self.balance
        time.sleep(4)
        self.balance = old_balance - num
        print('取錢成功!')
        # 解鎖
        self.lock.release()


acount1 = Account(1000, '余婷')

# 支付寶存錢
t1 = threading.Thread(target=acount1.save, args=(1000,))
# 銀行卡取錢
t2 = threading.Thread(target=acount1.draw, args=(500,))

t1.start()
t2.start()

t1.join()
t2.join()
print(acount1.balance)

開始存錢
開始取錢!
存錢成功敬辣!
取錢成功!
1500


07.多線程(一個(gè)服務(wù)器與多個(gè)客戶端)

服務(wù)器:

"""服務(wù)器"""

import socket
from threading import Thread


class ConversationThread(Thread):
    def __init__(self, conversation, addr):
        super().__init__()
        self.conversation = conversation
        self.addr = addr

    def run(self):
        while True:
            message = self.conversation.recv(1024).decode('utf-8')
            print(self.addr, ': ' + message, sep='')


server = socket.socket()
server.bind(('10.7.187.149', 9001))
server.listen(512)
while True:
    conversation, addr = server.accept()

    # 給服務(wù)器發(fā)送請(qǐng)求的客戶端建立的連接創(chuàng)建一個(gè)子線程达传。在子線程中去處理每個(gè)請(qǐng)求
    t = ConversationThread(conversation, addr)
    t.start()

客戶端:

"""客戶端"""

import socket

client = socket.socket()
client.connect(('10.7.187.149', 9000))
while True:
    message = input('自己:')
    client.send(message.encode('utf-8'))
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末陋气,一起剝皮案震驚了整個(gè)濱河市劳吠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巩趁,老刑警劉巖痒玩,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異议慰,居然都是意外死亡蠢古,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門别凹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)草讶,“玉大人,你說(shuō)我怎么就攤上這事炉菲《檎剑” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵拍霜,是天一觀的道長(zhǎng)嘱丢。 經(jīng)常有香客問(wèn)我,道長(zhǎng)祠饺,這世上最難降的妖魔是什么越驻? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮道偷,結(jié)果婚禮上缀旁,老公的妹妹穿的比我還像新娘。我一直安慰自己勺鸦,他們只是感情好诵棵,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著祝旷,像睡著了一般履澳。 火紅的嫁衣襯著肌膚如雪嘶窄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天距贷,我揣著相機(jī)與錄音柄冲,去河邊找鬼。 笑死忠蝗,一個(gè)胖子當(dāng)著我的面吹牛现横,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播阁最,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼戒祠,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了速种?” 一聲冷哼從身側(cè)響起姜盈,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎配阵,沒想到半個(gè)月后馏颂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡棋傍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年救拉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瘫拣。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡亿絮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出麸拄,到底是詐尸還是另有隱情壹无,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布感帅,位于F島的核電站斗锭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏失球。R本人自食惡果不足惜岖是,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望实苞。 院中可真熱鬧豺撑,春花似錦、人聲如沸黔牵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)猾浦。三九已至陆错,卻和暖如春灯抛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背音瓷。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工对嚼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人绳慎。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓纵竖,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親杏愤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子靡砌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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