Python多工(2.執行緒(建立執行緒的兩種方式))
Python中threading模組
可以總結出:
(1)當呼叫Thread的時候,不會建立執行緒
(2)呼叫Thread創建出來的例項物件的start方法的時候,才會建立執行緒以及讓這個執行緒開始執行
執行緒真正建立是呼叫start(),執行緒真正結束是主執行緒結束
(3)主執行緒會等待所有的子執行緒結束後才結束
(4)執行緒建立後誰先執行是不確定的,要確定先後的順序可以通過延時的方式來保證
(5)只要主執行緒一死,其他的子執行緒就會全部結束
下面看例子:
1. 用threading建立多執行緒來執行任務
單執行緒執行
import time def eat_fish(): print("--正在吃魚--") time.sleep(1) if __name__ == '__main__': for i in range(5): eat_fish() ''' 執行的結果, 一次只執行一次,5秒鐘執行完成 --正在吃糖果-- --正在吃糖果-- --正在吃糖果-- --正在吃糖果-- --正在吃糖果-- '''
多執行緒執行
t = threading.Thread(target=函式名) # 生成一個子執行緒物件
t.start() # 然後利用這個物件呼叫start()方法,,來建立一個子執行緒
import threading
import time
def eat_candy():
print("--正在吃糖果--")
time.sleep(1)
if __name__ == '__main__':
for i in range(5):
t = threading.Thread(target=eat_candy) # 給target傳入函式的名字
# 生成一個例項物件 t
t.start() # 啟動執行緒,即讓執行緒開始執行
'''
執行的結果, 一次就執行完成,花費1秒執行完成
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
'''
2. 檢視執行緒數
threading.enumerate() # 返回值是一個列表,裡面有當前執行的所有執行緒
(1) 迴圈檢視當前執行的執行緒
import threading
import time
def test1():
for i in range(3):
print("----test1---%d---"%i)
time.sleep(1)
'''如果建立Thread時執行的函式,執行結束那麼意味著 這個子執行緒就結束了'''
def test2():
for i in range(6):
print("----test2---%d---"%i)
time.sleep(1)
def main():
t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
t1.start()
t2.start()
while True:
print(threading.enumerate()) # 打印出執行緒的列表
'''所有的執行緒只剩一個的時候(即主執行緒)就退出'''
if len(threading.enumerate())<=1:
break
time.sleep(1)
if __name__ == '__main__':
main()
Thread執行的函式結束時,執行緒就結束了,所以列印執行緒的長度是就會少一個。
(2) 在使用Thread時,執行緒是從什麼時候開始建立的,什麼時候結束
import threading
import time
def test1():
for i in range(5):
print("----test1---%d---" % i)
time.sleep(1)
def main():
# 在呼叫Thread之前先列印當前執行緒資訊
print(threading.enumerate())
t1 = threading.Thread(target=test1)
# 在呼叫Thread之後列印
print(threading.enumerate())
t1.start()
# 在呼叫start()之後列印
print(threading.enumerate())
if __name__ == '__main__':
main()
結果:
3. 通過繼承Thread類完成建立執行緒
(1) 適合一個執行緒裡面做的事情比較複雜,而且分了多個函式來做,一般來封裝成一個類,
類裡面覆寫run()方法
用這個類的例項物件來呼叫start()方法
(2)如果類裡面還有其他的方法想要用子執行緒,
直接在run()方法裡面呼叫就行(例如:self.login())
如果直接用例項.方法名時,不會建立子執行緒
import threading
import time
class MyThread(threading.Thread):
def run(self):
for i in range(3):
time.sleep(1)
msg = "I'm"+self.name+"@"+str(i) # name 屬性中儲存的是當前執行緒的名字
print(msg)
def login(self):
pass
'''
如果類裡面還有其他的方法想要用子執行緒,
直接在run()方法裡面呼叫就行(例如:self.login())
如果直接用例項.方法名時,不會建立子執行緒,
'''
if __name__ == '__main__':
t = MyThread()
t.start() # 直接利用類的例項物件呼叫start()方法
執行結果: