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()方法
運行結果:
I'mThread-1@0
I'mThread-1@1
I'mThread-1@2