Python多線程threading模塊用法實(shí)例分析
本文實(shí)例講述了Python多線程threading模塊用法。分享給大家供大家參考,具體如下:
多線程 - threading
python的thread模塊是比較底層的模塊,python的threading模塊對(duì)thread做了一些包裝,可以更加方便的被使用。
1. 使用threading模塊
單線程執(zhí)行
#coding=utf-8
import time
def saySorry():
print('跑一圈')
time.sleep(1)
if __name__ == "__main__":
for i in range(5):
saySorry()
運(yùn)行結(jié)果:
跑一圈
跑一圈
跑一圈
跑一圈
跑一圈
多線程執(zhí)行
#coding=utf-8
import threading
import time
def saySorry():
print('跑一圈')
time.sleep(1)
if __name__ == "__main__":
for i in range(5):
t = threading.Thread(target=saySorry)
t.start()#啟動(dòng)線程
運(yùn)行結(jié)果:
跑一圈
跑一圈
跑一圈
跑一圈
跑一圈
說明
①. 通過運(yùn)行可以明顯看出使用多線程并發(fā)操作,花費(fèi)時(shí)間要短很多。
②. 創(chuàng)建好的線程,需要調(diào)用 start() 方法來啟動(dòng)
2. 主線程會(huì)等待所有的子線程結(jié)束后才結(jié)束
#coding=utf-8
import threading
from time import sleep,ctime,time
def run():
for i in range(3):
print('在跑步...%d'%i)
sleep(1)
def sing():
for i in range(3):
print('在唱歌...%d'%i)
sleep(1)
if __name__ == "__main__":
print('------start------' + ctime())
t1 = threading.Thread(target=run)
t2 = threading.Thread(target=sing)
t1.start()#啟動(dòng)線程
t2.start()
# sleep(5)# 屏蔽此行代碼,試試看,程序是否會(huì)立即結(jié)束?
print('------stop------' + ctime())
運(yùn)行結(jié)果:
------start------Thu Aug 24 13:38:28 2017
在跑步...0
------stop------Thu Aug 24 13:38:28 2017
在唱歌...0
在跑步...1
在唱歌...1
在跑步...2
在唱歌...2
3. 查看線程數(shù)量
#coding=utf-8
import threading
from time import sleep,ctime,time
def run():
for i in range(3):
print('在跑步...%d'%i)
sleep(1)
def sing():
for i in range(3):
print('在唱歌...%d'%i)
sleep(1)
if __name__ == "__main__":
print('------start------' + ctime())
t1 = threading.Thread(target=run)
t2 = threading.Thread(target=sing)
t1.start()#啟動(dòng)線程
t2.start()
while True:
length = len(threading.enumerate())
print('當(dāng)前運(yùn)行的線程數(shù)為:' , length , ctime())
if length <= 1:
break
# sleep(5)# 屏蔽此行代碼,試試看,程序是否會(huì)立即結(jié)束?
print('------stop------' + ctime())
運(yùn)行結(jié)果:
由于數(shù)量龐大,在此不展示。。。。。。
4.線程執(zhí)行代碼的封裝 - threading.Thread子類
#coding=utf-8
import threading
import time
class MyThread(threading.Thread):
def run(self):
for i in range(3):
time.sleep(1)
msg = 'i am '+self.name+'@'+str(i) #name屬性中保存的是當(dāng)前線程的名字
print(msg)
if __name__ == "__main__":
t = MyThread()
t.start()
運(yùn)行結(jié)果:
i am Thread-1@0
i am Thread-1@1
i am Thread-1@2
說明:
python的threading.Thread類有一個(gè)run方法,用于定義線程的功能函數(shù),可以在自己的線程類中覆蓋該方法。在創(chuàng)建自己的線程實(shí)例后,通過Thread類的start()方法,可以啟動(dòng)該線程,交給python虛擬機(jī)進(jìn)行調(diào)度,當(dāng)該線程獲得執(zhí)行的機(jī)會(huì)時(shí),就會(huì)調(diào)用run方法執(zhí)行線程。
5.線程的執(zhí)行順序
#coding=utf-8
import threading
import time
class MyThread(threading.Thread):
def run(self):
for i in range(3):
time.sleep(1)
msg = 'i am '+self.name+'@'+str(i) #name屬性中保存的是當(dāng)前線程的名字
print(msg)
def test():
for i in range(5):
t = MyThread()
t.start()
if __name__ == "__main__":
test()
運(yùn)行結(jié)果:
i am Thread-1@0
i am Thread-2@0
i am Thread-3@0
i am Thread-4@0
i am Thread-5@0
i am Thread-1@1
i am Thread-2@1
i am Thread-3@1
i am Thread-4@1
i am Thread-5@1
i am Thread-1@2
i am Thread-2@2
i am Thread-3@2
i am Thread-4@2
i am Thread-5@2
說明:
(運(yùn)行的結(jié)果可能不一樣,但是大體是一致的)
從代碼的執(zhí)行結(jié)果我們可以看出,多線程程序的執(zhí)行順序是不確定的。當(dāng)執(zhí)行到sleep語句時(shí),線程將被阻塞(Blocked),到sleep結(jié)束后,線程進(jìn)入就緒(Runnable)狀態(tài),等待調(diào)度。而線程調(diào)度將自行選擇一個(gè)線程執(zhí)行。上面的代碼中只能保證每個(gè)線程都運(yùn)行完整個(gè)run函數(shù),但是線程的啟動(dòng)順序、
run函數(shù)中每次循環(huán)的執(zhí)行順序都不能確定。
總結(jié)
1. 每個(gè)線程一定會(huì)有一個(gè)名字,盡管上面的例子中沒有指定線程對(duì)象的name,但是python會(huì)自動(dòng)為線程指定一個(gè)名字。
2. 當(dāng)線程的run()方法結(jié)束時(shí)該線程完成。
3. 無法控制線程調(diào)度程序,但可以通過別的方式來影響線程調(diào)度的方式。
4. 線程的幾種狀態(tài)

多線程-共享全局變量
#coding=utf-8
import threading
import time
g_num = 100
def work1():
global g_num
for i in range(3):
g_num+=1
print('work1 --- num = %d'%g_num)
def work2():
global g_num
print('work2 --- num = %d'%g_num)
if __name__ == "__main__":
print('---start------g_num = %d'%g_num)
t1 = threading.Thread(target=work1)
t1.start()
# 延時(shí)一會(huì),保證t1線程中的事情做完
time.sleep(1)
t2 = threading.Thread(target=work2)
t2.start()
運(yùn)行結(jié)果:
---start------g_num = 100
work1 --- num = 103
work2 --- num = 103
更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python進(jìn)程與線程操作技巧總結(jié)》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python入門與進(jìn)階經(jīng)典教程》、《Python+MySQL數(shù)據(jù)庫程序設(shè)計(jì)入門教程》及《Python常見數(shù)據(jù)庫操作技巧匯總》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
相關(guān)文章
釘釘群自定義機(jī)器人消息Python封裝的實(shí)例
今天小編就為大家分享一篇釘釘群自定義機(jī)器人消息Python封裝的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-02-02
Python使用requests庫進(jìn)行請(qǐng)求重試
在進(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí),由于網(wǎng)絡(luò)波動(dòng)、服務(wù)器繁忙等原因,可能會(huì)出現(xiàn)請(qǐng)求失敗的情況,為了提高請(qǐng)求的成功率,我們可以使用請(qǐng)求重試機(jī)制,本文就來講講如何在 Python 中使用 requests 庫進(jìn)行請(qǐng)求重試吧2023-06-06
使用XML庫的方式,實(shí)現(xiàn)RPC通信的方法(推薦)
下面小編就為大家?guī)硪黄褂肵ML庫的方式,實(shí)現(xiàn)RPC通信的方法(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
pandas.DataFrame刪除/選取含有特定數(shù)值的行或列實(shí)例
今天小編就為大家分享一篇pandas.DataFrame刪除/選取含有特定數(shù)值的行或列實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-11-11
Python內(nèi)建模塊collections實(shí)現(xiàn)特殊容器數(shù)據(jù)類型
collections模塊是Python的內(nèi)建模塊之一,它實(shí)現(xiàn)了特殊的容器數(shù)據(jù)類型,提供了Python內(nèi)建的數(shù)據(jù)類型dict、list、set、和tuple的高效替代選擇2023-06-06
解決keras GAN訓(xùn)練是loss不發(fā)生變化,accuracy一直為0.5的問題
這篇文章主要介紹了解決keras GAN訓(xùn)練是loss不發(fā)生變化,accuracy一直為0.5的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07
在Python的Django框架中創(chuàng)建和使用模版
這篇文章主要介紹了在Python的Django框架中創(chuàng)建和使用模版的方法,包括使用manage.py shell來幫助設(shè)置模版的方法,需要的朋友可以參考下2015-07-07
使用pycharm+conda配置虛擬環(huán)境的詳細(xì)步驟
這篇文章主要介紹了使用pycharm創(chuàng)建新的項(xiàng)目環(huán)境并使用conda進(jìn)行配置和使用pycharm引用已有的conda虛擬環(huán)境,文中通過圖文結(jié)合的方式介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05

