程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python常用模塊 之 threading和Thread模塊 第一階段 線程的實現

編輯:Python


目錄:

  •  ​引入:​​
  •  ​每篇前言:​​
  •  ​1. 線程​​
  •  ​1.1 線程模塊:​​
  •  ​1.1.1 Thread類:​​
  •  ​1.2 創建線程:​​
  •  ​1.2.1 實例Thread類法創建線程:​​
  •  ​1.2.1 繼承重寫Thread類法創建線程:​​
  •  ​1.3 Join & setDaemon​​
  •  ​1.3.1 join​​
  •  ​1.3.2 setDaemon​​

引入:

進
程
:
打
開
一
個
程
序
至
少
會
有
一
個
進
程
它
是
cpu
調
度
的
最
小
的
單
位
。

線 程 : 程 序 執 行 的 最 小 單 位 , 一 個 進 程 裡 面 至 少 有 一 個 線 程 , cpu 會 控 制 進 程 裡 面 的 線 程 。

打 個 比 方 : ( 1 ) 打 開 一 個 qq 就 是 一 個 進 程 的 話 , 那 麼 你 可 以 同 時 和 好 多 人 聊 天 , 和 一 個 人 聊 天 這 就 是 一 個 線 程 。
( 2 ) 再 打 個 比 方 , 一 條 直 行 的 高 速 公 路 , 分 好 幾 個 車 道 , 這 整 個 告 訴 公 路 就 相 當 於 一 個 進 程 ,
那 些 車 道 就 相 當 於 一 個 個 線 程 , 如 果 有 一 條 車 道 上 的 車 拐 彎 , 別 的 車 道 的 車 就 要 等 待 , 不 然 就 撞 車 了 。
注 意 :
( 1 ) 一 個 cpu 同 一 時 間 只 能 處 理 一 件 事 , 如 果 同 時 有 多 個 任 務 , 那 麼 就 輪 換 著 執 行 , 但 是 每 個 任 務 執 行 的 時 間 非 常 短 暫 , 無 法 感 受 到 。
( 2 ) 使 用 線 程 的 時 候 , 不 管 它 的 順 序 , 因 為 cpu 是 隨 機 調 度 的 。
( 3 ) 一 個 程 序 的 執 行 , 就 會 有 一 個 主 線 程
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

深入講解請看此篇:

  •  ​《有關於進程,線程and協程》​​

每篇前言:

作者介紹:【孤寒者】—全棧領域優質創作者、HDZ核心組成員、華為雲享專家Python全棧領域博主、原力計劃作者

  • 本文已收錄於Python全棧系列專欄:​ ​《Python全棧基礎教程》​​
  • 熱門專欄推薦:​ ​《Django框架從入門到實戰》、​​​ ​《爬蟲從入門到精通系列教程》、​​​ ​《爬蟲高級》、​​​ ​《前端系列教程》、​​​ ​《tornado一條龍+一個完整版項目》。​​
  • 本專欄面向廣大程序猿,為的是大家都做到Python從入門到精通,同時穿插有很多很多習題,鞏固學習。
  • 加入我一起學習進步,一個人可以走的很快,一群人才能走的更遠!

1. 線程

1.1 線程模塊:

  • Python通過兩個標准庫thread 和threading提供對線程的支持 , threading對thread進行了封裝。threading模塊中提供了Thread , Lock , RLock , Condition等組件。
  • 因此在實際的使用中我們一般都是使用threading。

1.1.1 Thread類:

常用參數說明:

  • target:表示調用對象,即子線程要執行的任務。
  • name:子線程的名稱。
  • args:傳入target函數中的位置參數,是一個元組,必須加逗號。

常用實例方法:

  • ​Thread.run(self)​​ 線程啟動時運行的方法,由該方法調用target參數所指定的函數。
  • ​Thread.start(self)​​ 啟動線程,start方法就是去幫你調用run方法。
  • ​Thread.terminate(self)​​ 強制終止線程。
  • ​Thread.join(self, timeout=None)​​ 阻塞調用,主線程進行等待。
  • ​Thread.setDaemon(self, daemonic)​​ 將子線程設置為守護線程。
  • ​Thread.getName(self, name)​​ 獲取線程名稱。
  • ​Thread.setName(self, name)​​ 設置線程名稱。

但是剛剛也講了實際使用中我們都是使用的threading模塊,所以此處只是簡單介紹一下Thread類,下面講解都是使用的threading模塊!

1.2 創建線程:

在python中創建線程有兩種方式:

  1. 實例Thread類;
  2. 繼承重寫Thread類。

1.2.1 實例Thread類法創建線程:

(需要注意的是:下面在主線程裡添加了t1,t2兩個子線程,①如果沒有設置setDaemon守護線程,那麼整個文件順序執行完[即主線程]之後,對應的兩個子線程並行執行;②如果設置了守護線程,那麼對應的設置了守護線程的子線程在主線程執行完之後立馬被殺死!)

# -*- coding: utf-8 -*-

"""
__author__ = 孤寒者
"""
import threading
import time

# 定義線程要運行的函數
def sing():
# 為了便於觀察,sleep1秒
for i in range( 5):
print( "正在唱歌......")
time. sleep( 1)

def dance():
# 為了便於觀察,sleep1秒
for i in range( 5):
print( "正在跳舞......")
time. sleep( 1)


if __name__ == '__main__':
# 創建兩個線程實例
t1 = threading. Thread( target = sing)
t2 = threading. Thread( target = dance)
# 設置守護線程
t1. setDaemon( True) # 守護線程:把子線程作為主線程的守護線程
t2. setDaemon( True)
# 啟動線程
t1. start()
t2. start()
print( '主線程結束')
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.

未設置t1,t2為守護線程時的輸出:

設置t1,t2為守護線程時的輸出:

1.2.1 繼承重寫Thread類法創建線程:

# -*- coding: utf-8 -*-

"""
__author__ = 孤寒者
"""
import threading
import time

# 繼承threading中的Thread類
class MyThread( threading. Thread):
# 線程中所需要的參數
def __init__( self, name):
super(). __init__()
self. name = name
# 重構run方法,注意這個是表示線程活動的方法,必須有!
def run( self):
print( 'I am %s' % self. name)
time. sleep( 2)

# 創建線程實例
t1 = MyThread( 'guhanzhe')
t2 = MyThread( 'coolboy')
# 啟動線程
t1. start()
t2. start()
# 打印線程名
print( t1. getName())
print( t2. getName())
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.

1.3 Join & setDaemon

在說這兩個方法之前 , 需要知道主線程與子線程的概念:

  • 主線程 : 當一個程序啟動時 , 就有一個線程開始運行 , 該線程通常叫做程序的主線程。
  • 子線程 : 因為程序是開始時就執行的 , 如果你需要再創建線程 , 那麼創建的線程就是這個主線程的子線程。

主線程的重要性體現在兩方面 :

  1. 是產生其他子線程的線程;
  2. 通常它必須最後完成執行比如執行各種關閉操作。

1.3.1 join

  • join : 阻塞調用程序 , 直到調用join () 方法的線程執行結束, 才會繼續往下執行。
# -*- coding: utf-8 -*-

"""
__author__ = 孤寒者
"""
import threading
import time

def run( name):
print( 'I am %s' % name)
time. sleep( 2)
print( '子線程結束......')

t1 = threading. Thread( target = run, args =( 'guhanzhe', ))
t1. start()
# 阻塞主線程,等待子線程運行結束
t1. join()
print( '主線程結束......')
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

大家可以嘗試不加join()的話輸出是什麼樣的哦~

1.3.2 setDaemon

  • setDaemon() 與 join() 基本上是相對的 , join會等子線程執行完畢 ; 而setDaemon則不會等,主線程結束,對應的設置了守護線程的子線程也會立馬被殺死。
# -*- coding: utf-8 -*-

"""
__author__ = 孤寒者
"""
import threading
import time

def run( name):
print( 'I am %s' % name)
time. sleep( 2)
print( '子線程結束......')

t1 = threading. Thread( target = run, args =( 'guhanzhe', ))
# 設置守護線程
t1. setDaemon( True)
t1. start()
print( '主線程結束......')
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.



  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved