python多任务编程_python线程的多任务编程
多任務(wù)
多任務(wù)介紹
對(duì)于人來說,一邊聽歌,一邊跳舞就是多任務(wù)。
對(duì)于電腦,簡(jiǎn)單的說,同一時(shí)間執(zhí)行多個(gè)程序處理數(shù)據(jù)叫做多任務(wù)
多任務(wù)理解
單核CPU
單核cpu在處理多任務(wù)的時(shí)候是根據(jù)時(shí)間片輪轉(zhuǎn)的方式進(jìn)行的,比如執(zhí)行QQ1us,然后切換微信執(zhí)行1us,最后是執(zhí)行釘釘1us,如此循環(huán)。因?yàn)閏pu的切換速度過快,導(dǎo)致我們認(rèn)為三個(gè)軟件是同時(shí)執(zhí)行的
多核cpu
并發(fā):當(dāng)cpu不能同時(shí)執(zhí)行當(dāng)前所有任務(wù)時(shí),就會(huì)循環(huán)執(zhí)行,是假的多任務(wù)
并行:當(dāng)cpu可以同時(shí)執(zhí)行當(dāng)前所有任務(wù)時(shí),是真的多任務(wù)
多任務(wù)的實(shí)現(xiàn)方式
實(shí)現(xiàn)多任務(wù)有三種方式:
線程
進(jìn)程
協(xié)程
線程
線程介紹
線程是指在一個(gè)單獨(dú)進(jìn)程中,對(duì)于CPU和內(nèi)存而言的多個(gè)工作單位,所有線程在進(jìn)程中的資源都是共享的,包括全局?jǐn)?shù)據(jù)、執(zhí)行代碼等。
線程的使用
先介紹三個(gè)方法
setDaemon(True): 主線程A中,創(chuàng)建了子線程B,并且在主線程A中調(diào)用了B.setDaemon(),這個(gè)的意思是,把主線程A設(shè)置為守護(hù)線程,這時(shí)候,要是主線程A執(zhí)行結(jié)束了,就不管子線程B是否完成,一并和主線程A退出.
join(): 主線程A中,創(chuàng)建了子線程B,并且在主線程A中調(diào)用了B.join(),那么,主線程A會(huì)在調(diào)用的地方等待,直到子線程B完成操作后,才可以接著往下執(zhí)行
enumerate(): 查看線程數(shù)量
使用
代碼示例import threading
import datetime
def A():
print('函數(shù)A')
print(datetime.datetime.now())
def B():
print('函數(shù)B')
print(datetime.datetime.now())
if __name__ == '__main__':
# 指定線程到A()和B()函數(shù)里執(zhí)行
t1 = threading.Thread(target=A)
t2 = threading.Thread(target=B)
# 執(zhí)行線程
t1.start()
t2.start()
print('--end--')
從輸出結(jié)果可以知道,兩個(gè)線程是在同一時(shí)間一起執(zhí)行的。不過因?yàn)閾屨际降奶攸c(diǎn),最后一條語句print('--end--')有時(shí)會(huì)在子線程的前面執(zhí)行。
join()方法的使用
如果我們想讓print('--end--')在最后執(zhí)行,可以用到j(luò)oin()方法,當(dāng)子線程結(jié)束后,主線程才會(huì)結(jié)束。
join方法的使用,代碼示例
import threading
import datetime
def A():
print('函數(shù)A')
print(datetime.datetime.now())
def B():
print('函數(shù)B')
print(datetime.datetime.now())
if __name__ == '__main__':
# 指定線程到A()和B()函數(shù)里執(zhí)行
t1 = threading.Thread(target=A)
t2 = threading.Thread(target=B)
# 執(zhí)行線程
t1.start()
t2.start()
t1.join()
t2.join()
print('--end--')
setDaemon()方法的使用
如果不想讓主線程等待子線程完成后才結(jié)束,可以使用setDaemon
代碼示例import threading
import time
def A():
for i in range(3):
print("A")
time.sleep(1)
if __name__ == '__main__':
t1 = threading.Thread(target=A)
t1.setDaemon(True) # 要放在線程開始之前
t1.start()
enumerate()的使用,查看線程數(shù)量
代碼示例import threading
import datetime
def A():
print('函數(shù)A')
print(datetime.datetime.now())
def B():
print('函數(shù)B')
print(datetime.datetime.now())
if __name__ == '__main__':
# 創(chuàng)建兩個(gè)主線程,指定線程到A()和B()函數(shù)里執(zhí)行
t1 = threading.Thread(target=A)
t2 = threading.Thread(target=B)
# 執(zhí)行線程
t1.start()
t2.start()
print(threading.enumerate())
print('--end--')
子線程的創(chuàng)建與執(zhí)行
當(dāng)我們調(diào)用start()方法時(shí),子線程才會(huì)被創(chuàng)建,并且執(zhí)行
繼承Thread類創(chuàng)建線程
我們可以通過修改Thread類的run()方法里的代碼,來完成重寫run()方法
代碼示例import threading
class T(threading.Thread):
def run(self):
self.a()
def a(self):
for i in range(3):
print('a')
if __name__ == '__main__':
t1 = T()
t1.start() # 當(dāng)調(diào)用start()方法時(shí),會(huì)主動(dòng)調(diào)用run()方法
當(dāng)我們調(diào)用start()方法時(shí),會(huì)主動(dòng)調(diào)用run()方法
多線程共享全局變量
代碼示例import threading
def a():
global num
num += 1
print(f'a:{num}')
def b():
print(f'b:{num}')
if __name__ == '__main__':
num = 10
print(num)
t1 = threading.Thread(target=a)
t2 = threading.Thread(target=b)
t1.start()
t2.start()
print(num)
線程的傳參
當(dāng)用線程去函數(shù)里執(zhí)行代碼時(shí),我們可以看到函數(shù)后邊是沒有括號(hào)()的,所以涉及到傳參的時(shí)候我們?cè)撛趺唇鉀Q這個(gè)問題?
解決方法
我們可以使用args參數(shù)進(jìn)行傳參,參數(shù)為元組
當(dāng)我們想要傳入字典時(shí),可以使用kwargs進(jìn)行傳入
代碼示例import threading
def a(x):
print(x)
def b(**kwargs):
print(kwargs)
if __name__ == '__main__':
num = 1
# 使用args參數(shù)進(jìn)行傳參
t1 = threading.Thread(target=a, args=(num,))
# 使用kwargs參數(shù)進(jìn)行傳入字典
t2 = threading.Thread(target=b, kwargs={"A": 1})
t1.start()
t2.start()
線程的資源搶占
代碼示例import threading
def a(x):
global num
for i in range(x):
num += 1
print(f'a: {num}')
def b(x):
global num
for i in range(x):
num += 1
print(f'b: {num}')
if __name__ == '__main__':
num = 100
t1 = threading.Thread(target=a, args=(1000000, ))
t2 = threading.Thread(target=b, args=(1000000, ))
t1.start()
t2.start()
print(num)
運(yùn)行結(jié)果
正常的結(jié)果應(yīng)該是2000100,但是因?yàn)橘Y源搶占導(dǎo)致數(shù)據(jù)不正確,使用鎖就可以避免這個(gè)問題,下篇博客我會(huì)細(xì)講怎么解決這個(gè)問題。
最后,有喜歡博主寫的內(nèi)容的伙伴可以點(diǎn)贊收藏加關(guān)注哦!
本文地址:https://blog.csdn.net/weixin_44604586/article/details/107091271
如您對(duì)本文有疑問或者有任何想說的,請(qǐng)點(diǎn)擊進(jìn)行留言回復(fù),萬千網(wǎng)友為您解惑!
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的python多任务编程_python线程的多任务编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 太强了,头发丝完整保留!一个开源的 Py
- 下一篇: B. All the Vowels Pl