一、多線程技術(shù)
1,主線程
每個進(jìn)程默認(rèn)都會有一個線程,這個線程我們一般叫他主線程
默認(rèn)情況下,所有的代碼都是在主線程中執(zhí)行
2,子線程
一個進(jìn)程中可以有多個線程。除了主線程以外,其他的線程需要手動添加
3,threading是python中的一個內(nèi)置模塊,用來支持多線程
a,Thread類的對象就是線程對象,需要線程的時候,就創(chuàng)建這個類或者這個類的子類對象
b,threading.currentThread()--->用來獲取當(dāng)前線程對象
導(dǎo)入模塊及創(chuàng)建函數(shù)
import threading
import datetime
import time
print(threading.currentThread())
# 下載兩個電影
def download(file):
print('開始下載:',datetime.datetime.now())
# 讓線程阻塞10秒
time.sleep(10)
print(file+'下載結(jié)束',datetime.datetime.now())
# 1,在主線程中下載兩個電影
download('終結(jié)者2')
download('沉默的羔羊')
# 2,在兩個子線程中下載兩個電影
threading.Thread(target,args)
target:需要在子線程中調(diào)用的函數(shù)的函數(shù)名
args:函數(shù)的實參
返回值:創(chuàng)建好的線程
t1=threading.Thread(target=download,args=('終結(jié)者',))
t2=threading.Thread(target=download,args=('沉默的羔羊',))
# 開始執(zhí)行t1對應(yīng)的線程任務(wù)
t1.start()
# 想要在子線程中執(zhí)行任務(wù),必須通過線程對象調(diào)用start方法才行
t2.start()
二、面向?qū)ο蟮亩嗑€程技術(shù)
1,聲明一個類繼承自Thread類
2,重寫run方法,將需要在子線程中執(zhí)行的任務(wù)放到run方法中
3,在需要子線程的位置去創(chuàng)建這個類的對象,然后用對象調(diào)用start方法去執(zhí)行run中的任務(wù)
from threading import Thread
import datetime
import time
==================================
class DownloadThread(Thread):
def __init__(self,files):
super().__init__()
self.files=files
def run(self):
print(self.files+'開始下載',datetime.datetime.now())
time.sleep(5)
print(self.files+'下載結(jié)束',datetime.datetime.now())
# ===============================================
print('=========================')
t1=DownloadThread('沉默的羔羊')
t1.start()
print('++++++++++++++++++++++++')
三、join方法的使用
在兩個子線程中下載兩個電影,在主線程中去統(tǒng)計兩個電影下載的總的時間
如果希望某個線程結(jié)束后再執(zhí)行某個操作,就用那個線程對象調(diào)用join函數(shù)
from threading import Thread
import time
from datetime import datetime
from random import randint
======================================
class DownloadThread(Thread):
def __init__(self,file):
super().__init__()
self.file=file
def run(self):
print(self.file + '開始下載', datetime.now())
time.sleep(randint(5,10))
print(self.file + '下載結(jié)束', datetime.now())
t1=DownloadThread('美麗的人生')
t2=DownloadThread('怦然心動')
start_time=time.time()
t1.start()
t2.start()
# 系統(tǒng)t1,t2中的代碼都結(jié)束后才執(zhí)行下面的代碼
t1.join()
t2.join()
end=time.time()
print(end-start_time)
四、線程間的數(shù)據(jù)共享
from threading import Thread,Lock,RLock
import time
from datetime import datetime
from random import randint
=======================================
模擬多個人對同一個賬號進(jìn)行操作
class Account:
def __init__(self,balance):
self.balance=balance
# 創(chuàng)建鎖對象
self.lock=Lock()
self.lock = RLock()
# 存錢的過程:讀出原來的余額,確定錢的一系列操作,將原來的余額加上存的數(shù)額產(chǎn)生最新的余額再保存
def save_money(self,amount):
''' 存錢 '''
# 獲取原來的余額
# 加鎖
self.lock.acquire()
old_amount=self.balance
# 模擬時間消耗
time.sleep(5)
# 修改余額
self.balance=old_amount+amount
print('存錢成功,最新余額:',self.balance)
# 解鎖
self.lock.release()
def get_money(self,amount):
''' 取錢 '''
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)前余額為%.2f'%self.balance)
account=Account(10000)
# account.save_money(1000)
# account.show_balance()
# account.get_money(400)
# account.show_balance()
t1=Thread(target=account.save_money,args=(1000,))
t2=Thread(target=account.get_money,args=(500,))
t1.start()
t2.start()