執行緒(Thread)基本用法

2022-11-19 18:00:16

一.執行緒的呼叫

1.無參

def run_01():
    for i in range(6, 10):
        print("test01", i)
        time.sleep(1)


th_01 = threading.Thread(target=run_01)  # 建立執行緒
th_01.start()  # 啟動執行緒

for i in range(0, 5):
    print("main", i)
    time.sleep(1)

threading中最主要的類就是Thread,我們可通過範例化Thread類來建立一個子執行緒,target引數為執行的事件。

start()方法為啟動執行緒,執行緒執行結束或報異常時自動會結束執行緒。

程式預設在主執行緒上執行,不做任何操作的話,子執行緒和主執行緒是同步進行的。

2.有參

def run_01(a):
    for i in range(6, 10):
        print("test01", i)
        time.sleep(1)


th_01 = threading.Thread(target=run_01, args=("test",))  # 建立執行緒
th_01.start()  # 啟動執行緒

若執行的事件有引數時,我們可通過args傳入一個元組入參,也可通過kwargs傳入字典型別。

def run_01(a):
    for i in range(6, 10):
        print("test01", i)
        time.sleep(1)


th_01 = threading.Thread(target=run_01, kwargs={"a": "test"})  # 建立執行緒
th_01.start()  # 啟動執行緒

key值要與引數值保持一致。

3.多參

def run_01(a, b):
    for i in range(6, 10):
        print("test01", i)
        time.sleep(1)


th_01 = threading.Thread(target=run_01, args=(1, 2))  # 建立執行緒
# or
# th_01 = threading.Thread(target=run_01, kwargs={"a": "test", "b": 1})  # 建立執行緒
th_01.start()  # 啟動執行緒

和單個入參差不多,多傳入一個引數即可。

二.設定執行緒名稱,獲取執行緒狀態

1.子執行緒名稱預設是Thread-1,Thread-2.....,我們可通過Thread類中name屬性設定執行緒名,

def run():
    for i in range(0, 5):
        print(i)


thread = threading.Thread(target=run, name='test')  # name設定執行緒名
print(thread.name, thread.getName())  # name,getname()方法獲取執行緒名

通過name屬性和getName()方法獲取執行緒名。修改/裝置執行緒名也可通過setName()方法設定。

thread = threading.Thread(target=run, name='test')  # name設定執行緒名
thread.setName("updateThreadName")
print(thread.name, thread.getName())  # name,getName()方法獲取執行緒名

2.is_alive()為獲取執行緒當前的執行狀態

def run():
    for i in range(0, 5):
        print(i)


thread = threading.Thread(target=run, name='test')  # name設定執行緒名
thread.start()
bol = thread.is_alive()  # 為true時表示正在執行,為false時停止執行
print(bol)

三.主/子執行緒執行順序

1.預設情況下主/子執行緒會同時執行,主執行緒會等待子執行緒結束後再結束。

def run():
    for i in range(0, 5):
        print("thread", i)
        time.sleep(2)


if __name__ == '__main__':
    thread = threading.Thread(target=run)
    thread.start()
    for i in range(5, 10):
        print("main", i)
        time.sleep(1)

2.Thread類中有個daemon屬性可控制執行結果

if __name__ == '__main__':
    thread = threading.Thread(target=run,daemon=True)
    thread.start()
    for i in range(5, 10):
        print("main", i)
        time.sleep(1)

建立子執行緒時我們將daemon設定為True,可以看出主執行緒結束後子執行緒也會結束執行,

不會等待子執行緒結束後再結束。也可通過setDaemon()方法設定。

if __name__ == '__main__':
    thread = threading.Thread(target=run)
    thread.setDaemon(True)
    thread.start()
    for i in range(5, 10):
        print("main", i)
        time.sleep(1)

四.join()用法

1.join()為堵塞主執行緒執行,優先執行子執行緒,等子執行緒執行完後再去執行主執行緒。

def run():
    for i in range(0, 5):
        print("thread1", i)
        time.sleep(1)


def run2():
    for i in range(0, 5):
        print("thread2", i)
        time.sleep(1)


if __name__ == '__main__':
    thread = threading.Thread(target=run)
    thread2 = threading.Thread(target=run2)
    thread.start()
    thread.join()  # 開始堵塞主執行緒,只執行thread執行緒
    thread2.start()

    for i in range(5, 10):
        print("main", i)
        time.sleep(1)

2.join(timeout=None)中timeout引數

timeout預設為None,可傳遞秒數,設定堵塞主執行緒的時間,timeout秒後不管子執行緒有沒有執行完都會執行主執行緒。

thread.join(timeout=2.0)

五.Event()方法的使用

我們都知道一個程序有多個執行緒,多個執行緒之間的資源是共用的,那麼如果多個執行緒去修改同

一個資源資料,就會出現資料錯亂的情況。Event類可以去堵塞執行緒的執行,我們先來看下Event()的幾個方法。

1.範例化Event()類

event = threading.Event()

Event()中有個_flag的私有屬性,預設為false,表示堵塞

2.wait()呼叫後表示開始堵塞

event.wait(timeout=2.0)  # 呼叫該方法後,該執行緒會被堵塞,timeout為堵塞時間

3.set()方法設定flag為true,表示結束堵塞

event.set()  # 設定self._flag = True

4.清除設定,flag值恢復false,繼續堵塞

event.clear()  # self._flag = False

5.is_set()檢視flag的值

print(event.is_set())  # 檢視當前_flag的值

6.範例

import threading
import time


def run(event):
    print("當前flag的值", event.is_set())
    event.wait()  # 開始堵塞
    for i in range(1, 6):
        print(i)
        time.sleep(1)
        if event.is_set() == False:
            break


event = threading.Event()  # self._flag = False
thread = threading.Thread(target=run, args=(event,))
thread.start()
print("\n開始堵塞2s")
time.sleep(2)
event.set()  # 設定self._flag = True
print("結束堵塞,執行2s")
time.sleep(2)
print("結束執行,跳出for迴圈")
event.clear()  # self._flag = False

解析:

上述中,子執行緒執行到event.wait()時就開始進行堵塞,主執行緒等待2s後呼叫set()方法使子執行緒繼續執行,

子執行緒迴圈兩次後主執行緒呼叫clear()設定flag值為false,子執行緒if判斷跳出迴圈,執行結束。

 

 

 

 

 

 

 

 

文章來源:https://www.cnblogs.com/lihongtaoya/ ,請勿轉載