Python | threading01 - 创建两个同时运行的子线程
文章目錄
- 一、前言
- 二、創建兩個同時運行的線程
- 2.1、代碼
- 2.2、運行
- 三、threading庫的函數
- 3.1、threading.Thread()
- 3.2、threading.join()
- 3.3、threading.start()
- 四、最終的完整代碼
一、前言
使用threading庫,咱們的python程序就能從單線程串行變成多線程并發。python的threading庫實現的“并發”是假的并發,即同一時刻只有一個線程在運行。據說python后來想將這個假的“并發”改為真的并發,但出現特別多的BUG,最后放棄了這個想法。
聊到假的“并行”,學習過單片機(STM32)的嵌入式實時系統RTOS(ucosIII、freeRTOS、RTX5等)的同學就知道,移植了RTOS的單片機,同一時刻僅僅只有一個線程在運行。只是RTOS在很快的切換線程,產生了好像多個線程在同時工作的“假象”。
python多線程與單片機的RTOS在調度規則完全不一樣。python多線程的調度程序會在任何時候中斷線程(相當于調度,所以python多線程的調度可以說是很難控制的),單片機的RTOS會有相應的API來產生調度(調度是可控的)。
線程與協程之間的比較還有最后一點要說明:如果使用線程做過重要的編程,就知道寫出程序有多么困難,因為調度程序任何時候都可能中斷線程。必須記住保留鎖,去保護程序中的重要部分,防止多步操作在執行的過程中被中斷,防止數據處于無效狀態。 —《流暢的Python》- Luciano Ramalho
所以,在我看來:python的協程與單片機的RTOS才是相似的。
二、創建兩個同時運行的線程
2.1、代碼
# python3.9 import time import threadingdef thread1():"""線程1"""while True:# 打印信息,并打印性能計數器的值print("I am thread1,time is %f" % time.perf_counter())time.sleep(1) # 休眠1秒def thread2():"""線程2"""while True:# 打印信息,并打印性能計數器的值print("I am thread2,time is %f" % time.perf_counter())time.sleep(1) # 休眠1秒def main():"""主線程"""t1 = threading.Thread(target=thread1) # 創建thread1線程t2 = threading.Thread(target=thread2) # 創建thread2線程t1.start() # 啟動thread1線程t2.start() # 啟動thread2線程if __name__ == "__main__":main()2.2、運行
從下圖可以看到,線程1與線程2都是每隔約1秒時間運行一次。線程1與線程2哪個先運行取決于系統的調度。
三、threading庫的函數
3.1、threading.Thread()
入口參數:
- group - 暫時不使用
- target - 用于執行線程需要執行的線程函數
- name - 可以自定義線程的名字,不設置的話,系統就自動分配
- args - 創建線程時,可以給線程函數傳遞參數
- kwargs - 暫時不使用
- daemon - 設置線程是否為守護線程(后臺線程)
當我們不對入口參數name賦值的話,系統會自動分配線程名字。
運行代碼:
接著,我嘗試對入口參數name進行賦值。
運行代碼:
另外一個重要的入口參數是daemon,它的作用是設置線程是否為守護線程(后臺線程)。守護線程有一個重要的特點是主線程(例子的main()線程)退出時,守護線程不管怎樣都要跟主線程一起退出。
守護線程的目的與作用:
所以,我的理解是:當創建的子線程是無限循環的話,就應該設置為守護線程。隨著主線程的退出,子線程被強制退出,保證了整個python程序正常地,完整地退出。
運行結果:
main()線程退出,線程t1與t2也跟著退出了。有什么辦法解決這個問題?
3.2、threading.join()
join()方法可以讓主線程進入阻塞態,等待其他線程運行結束,接著才解除阻塞態。
3.3、threading.start()
start()方法用于啟動線程的運行,否則線程不會跑起來。
四、最終的完整代碼
總結
以上是生活随笔為你收集整理的Python | threading01 - 创建两个同时运行的子线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RTX5 | 配置文件RTX_Confi
- 下一篇: mongodb 存储过程 遍历表数据_m