亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python使用thread模塊實現(xiàn)多線程的操作

 更新時間:2024年10月24日 10:29:31   作者:寒秋丶  
線程(Threads)是操作系統(tǒng)提供的一種輕量級的執(zhí)行單元,可以在一個進程內(nèi)并發(fā)執(zhí)行多個任務(wù),每個線程都有自己的執(zhí)行上下文,包括棧、寄存器和程序計數(shù)器,本文給大家介紹了Python使用thread模塊實現(xiàn)多線程的操作,需要的朋友可以參考下

介紹:

線程(Threads)是操作系統(tǒng)提供的一種輕量級的執(zhí)行單元,可以在一個進程內(nèi)并發(fā)執(zhí)行多個任務(wù)。每個線程都有自己的執(zhí)行上下文,包括棧、寄存器和程序計數(shù)器。

在Python中,可以使用threading模塊創(chuàng)建和管理線程。線程可以同時執(zhí)行多個任務(wù),可以在一個線程中執(zhí)行耗時操作,而不會阻塞其他線程的執(zhí)行。線程之間共享進程的資源,如內(nèi)存空間,因此需要注意線程安全的問題。

然而,Python的線程在特定情況下可能會受到全局解釋器鎖(Global Interpreter Lock,GIL)的限制。GIL是一種機制,它確保同一時刻只有一個線程可以執(zhí)行Python字節(jié)碼。這意味著在多線程場景下,即使有多個線程,也無法真正實現(xiàn)并行執(zhí)行。因此,在CPU密集型的任務(wù)中,Python的線程并不能充分利用多核處理器的能力。

1、導(dǎo)入threading模塊

在使用Python線程之前,首先需要導(dǎo)入 threading 模塊??梢允褂靡韵抡Z句導(dǎo)入該模塊:

import threading

2、創(chuàng)建線程

使用 threading.Thread 類創(chuàng)建線程對象??梢酝ㄟ^傳遞一個可調(diào)用的目標(biāo)函數(shù)和其他參數(shù)來實例化線程對象。目標(biāo)函數(shù)是線程實際執(zhí)行的任務(wù)。

# 定義一個目標(biāo)函數(shù)作為線程的執(zhí)行任務(wù)
def my_task(arg1, arg2):
    # 執(zhí)行任務(wù)的代碼
 
# 創(chuàng)建線程對象
my_thread = threading.Thread(target=my_task, args=(arg1, arg2))

3、啟動線程

通過調(diào)用線程對象的 start() 方法來啟動線程。啟動線程后,它將在后臺運行,執(zhí)行目標(biāo)函數(shù)中的代碼。

my_thread.start()

4、等待線程完成

可以使用 join() 方法等待線程執(zhí)行完畢。調(diào)用 join() 方法會阻塞當(dāng)前線程,直到目標(biāo)線程執(zhí)行完成。

my_thread.join()

5、線程同步

在多線程編程中,線程之間的同步是一項重要的任務(wù),旨在確保線程按照預(yù)期的順序執(zhí)行,并避免競態(tài)條件和數(shù)據(jù)不一致的問題。Python提供了幾種同步原語,常用的包括鎖(Lock)、信號量(Semaphore)、事件(Event)和條件變量(Condition)。下面詳細介紹這些同步原語的特點和使用方法:

鎖(Lock)

鎖是一種最基本的同步原語,在Python中由 threading.Lock 類實現(xiàn)。它提供了兩個主要方法:acquire() 和 release()。一個線程可以通過調(diào)用 acquire() 來獲取鎖,如果鎖當(dāng)前沒有被其他線程持有,則該線程將獲得鎖并繼續(xù)執(zhí)行,否則將被阻塞直到鎖被釋放。當(dāng)線程完成對臨界區(qū)的訪問后,應(yīng)該調(diào)用 release() 來釋放鎖,以便其他線程可以獲取它。

import threading
 
# 創(chuàng)建鎖對象
lock = threading.Lock()
 
# 線程函數(shù)
def thread_function():
    lock.acquire()
    # 臨界區(qū)代碼
    lock.release()

鎖還支持上下文管理器的使用方式,可以使用 with 語句來自動獲取和釋放鎖:

import threading
 
# 創(chuàng)建鎖對象
lock = threading.Lock()
 
# 線程函數(shù)
def thread_function():
    with lock:
        # 臨界區(qū)代碼

信號量(Semaphore)

信號量是一種更高級的同步原語,用于控制對共享資源的并發(fā)訪問。Python中的信號量由 threading.Semaphore 類實現(xiàn)。信號量維護一個內(nèi)部計數(shù)器,線程可以通過調(diào)用 acquire() 來減少計數(shù)器的值,如果計數(shù)器為零,則線程將被阻塞。線程在完成對共享資源的訪問后,應(yīng)該調(diào)用 release() 來增加計數(shù)器的值,以便其他線程可以獲取信號量。

import threading
 
# 創(chuàng)建信號量對象
semaphore = threading.Semaphore(value=3)  # 設(shè)置初始計數(shù)器值為3
 
# 線程函數(shù)
def thread_function():
    semaphore.acquire()
    # 訪問共享資源
    semaphore.release()

信號量的計數(shù)器可以控制同時訪問共享資源的線程數(shù)量。

事件(Event)

事件是一種用于線程間通信的同步原語,由 threading.Event 類實現(xiàn)。事件有兩種狀態(tài):已設(shè)置和未設(shè)置。線程可以通過調(diào)用 set() 來設(shè)置事件,將其狀態(tài)設(shè)置為已設(shè)置;通過調(diào)用 clear() 可以將事件狀態(tài)設(shè)置為未設(shè)置。線程可以通過調(diào)用 wait() 來等待事件的設(shè)置,如果事件已設(shè)置,則線程可以繼續(xù)執(zhí)行,否則將被阻塞。

import threading
 
# 創(chuàng)建事件對象
event = threading.Event()
 
# 線程函數(shù)
def thread_function():
    event.wait()  # 等待事件設(shè)置
    # 執(zhí)行操作
 
# 主線程設(shè)置事件
event.set()

事件還可以使用 is_set() 方法來檢查事件的狀態(tài)。

條件變量(Condition)

條件變量是一種復(fù)雜的同步原語,由 threading.Condition 類實現(xiàn)。它提供了一個條件隊列,允許線程等待某個條件的發(fā)生。條件變量結(jié)合鎖一起使用,可以實現(xiàn)更復(fù)雜的線程間同步。

import threading
 
# 創(chuàng)建條件變量對象
condition = threading.Condition()
 
# 線程函數(shù) A
def thread_function_a():
    with condition:
        while not condition_predicate():
            condition.wait()
        # 執(zhí)行操作
 
# 線程函數(shù) B
def thread_function_b():
    with condition:
        # 修改條件
        condition.notify()  # 通知等待的線程
 
# 主線程
with condition:
    # 修改條件
    condition.notify()  # 通知等待的線程

在線程函數(shù) A 中,線程會等待條件謂詞成立的情況下才繼續(xù)執(zhí)行,否則會調(diào)用 wait() 方法將線程掛起。線程函數(shù) B 可以在某個條件發(fā)生變化時調(diào)用 notify() 方法來通知等待的線程。

6、共享數(shù)據(jù)

共享數(shù)據(jù)是指多個線程同時訪問和修改的數(shù)據(jù)。當(dāng)多個線程同時讀寫共享數(shù)據(jù)時,可能會發(fā)生競態(tài)條件(Race Condition)和數(shù)據(jù)損壞的問題。為了確保線程安全性,需要采取適當(dāng)?shù)耐酱胧﹣肀Wo共享數(shù)據(jù)。以下是一些常用的同步機制和技術(shù):

鎖(Lock)

鎖是一種最常見的同步原語,用于保護共享數(shù)據(jù)的互斥訪問。在多線程環(huán)境中,一個線程可以通過獲取鎖來獨占地訪問共享數(shù)據(jù),其他線程必須等待鎖釋放后才能訪問。鎖可以使用 threading.Lock 類來實現(xiàn),通過調(diào)用 acquire() 和 release() 方法來獲取和釋放鎖。

import threading
 
# 創(chuàng)建鎖對象
lock = threading.Lock()
 
# 共享數(shù)據(jù)
shared_data = 0
 
# 線程函數(shù)
def thread_function():
    global shared_data
    lock.acquire()
    # 訪問和修改共享數(shù)據(jù)
    shared_data += 1
    lock.release()

在訪問共享數(shù)據(jù)之前獲取鎖,確保同一時間只有一個線程可以修改數(shù)據(jù),從而避免競態(tài)條件。

信號量(Semaphore)

信號量也可以用于保護共享數(shù)據(jù)的訪問,在多線程環(huán)境中控制并發(fā)訪問的數(shù)量。信號量維護一個內(nèi)部計數(shù)器,線程在訪問共享數(shù)據(jù)之前通過獲取信號量來減少計數(shù)器的值,如果計數(shù)器為零,則線程將被阻塞。線程在完成對共享數(shù)據(jù)的訪問后,通過釋放信號量來增加計數(shù)器的值,從而允許其他線程繼續(xù)訪問。

import threading
 
# 創(chuàng)建信號量對象
semaphore = threading.Semaphore()
 
# 共享數(shù)據(jù)
shared_data = 0
 
# 線程函數(shù)
def thread_function():
    global shared_data
    semaphore.acquire()
    # 訪問和修改共享數(shù)據(jù)
    shared_data += 1
    semaphore.release()

通過適當(dāng)設(shè)置信號量的初始值,可以控制同時訪問共享數(shù)據(jù)的線程數(shù)量。

其他同步原語

Python還提供了其他一些同步原語,如條件變量(Condition)和事件(Event)。它們可以用于更復(fù)雜的同步需求,如線程之間的通信和等待特定條件的發(fā)生。

import threading
 
# 創(chuàng)建條件變量對象
condition = threading.Condition()
 
# 共享數(shù)據(jù)
shared_data = []
 
# 線程函數(shù) A
def thread_function_a():
    with condition:
        while not condition_predicate():
            condition.wait()
        # 訪問和修改共享數(shù)據(jù)
 
# 線程函數(shù) B
def thread_function_b():
    with condition:
        # 修改條件
        condition.notify()  # 通知等待的線程

在上述示例中,線程函數(shù) A等待條件謂詞成立的情況下才能訪問共享數(shù)據(jù),線程函數(shù) B在條件發(fā)生變化時通過 notify() 方法通知等待的線程。

7、線程狀態(tài)

線程狀態(tài)是指線程在不同的時間點上所處的狀態(tài),它反映了線程的執(zhí)行情況和可用性。在多線程編程中,線程可以處于以下幾種不同的狀態(tài):

新建(New)狀態(tài)

當(dāng)創(chuàng)建線程對象但尚未啟動線程時,線程處于新建狀態(tài)。此時線程對象已經(jīng)被創(chuàng)建,但尚未分配系統(tǒng)資源和執(zhí)行代碼??梢酝ㄟ^實例化線程類或者從線程池中獲取線程來創(chuàng)建新線程。

import threading
 
# 創(chuàng)建新線程對象
thread = threading.Thread(target=thread_function)

就緒(Runnable)狀態(tài)

當(dāng)線程準(zhǔn)備好執(zhí)行,但由于系統(tǒng)調(diào)度的原因還未開始執(zhí)行時,線程處于就緒狀態(tài)。線程已經(jīng)分配了系統(tǒng)資源,并且等待調(diào)度器將其放入運行隊列中。多個就緒狀態(tài)的線程可能會競爭CPU資源,調(diào)度器會根據(jù)調(diào)度算法決定哪個線程被選中執(zhí)行。

運行(Running)狀態(tài)

當(dāng)線程獲得CPU資源并開始執(zhí)行線程函數(shù)時,線程處于運行狀態(tài)。此時線程的代碼正在被執(zhí)行,它可能會與其他線程并發(fā)執(zhí)行或通過時間片輪轉(zhuǎn)進行切換。只有一個線程可以處于運行狀態(tài)。

阻塞(Blocked)狀態(tài)

當(dāng)線程被暫停執(zhí)行,等待某個條件的發(fā)生時,線程處于阻塞狀態(tài)。在阻塞狀態(tài)下,線程不會占用CPU資源,直到滿足特定條件后才能繼續(xù)執(zhí)行。常見的阻塞原因包括等待I/O操作、獲取鎖失敗、等待其他線程的通知等。

終止(Terminated)狀態(tài)

當(dāng)線程完成了它的執(zhí)行任務(wù)或被顯式終止時,線程處于終止?fàn)顟B(tài)。線程函數(shù)執(zhí)行完畢或者出現(xiàn)異常時,線程將自動終止。也可以通過調(diào)用線程對象的 join() 方法來等待線程執(zhí)行完畢。

# 等待線程執(zhí)行完畢
thread.join()

線程狀態(tài)之間可以相互轉(zhuǎn)換,線程的狀態(tài)轉(zhuǎn)換通常由操作系統(tǒng)的調(diào)度器和線程的執(zhí)行情況決定。例如,當(dāng)線程處于就緒狀態(tài)并獲得CPU資源時,它將進入運行狀態(tài);當(dāng)線程在執(zhí)行期間發(fā)生阻塞,它將進入阻塞狀態(tài);當(dāng)線程執(zhí)行完畢或被終止時,它將進入終止?fàn)顟B(tài)。

8、線程屬性和方法

threading.Thread 類提供了一些屬性和方法來管理和操作線程。其中一些常用的屬性和方法包括:

  • name:獲取或設(shè)置線程的名稱。
  • ident:獲取線程的標(biāo)識符。
  • is_alive():檢查線程是否處于活動狀態(tài)。
  • setDaemon(daemonic):將線程設(shè)置為守護線程,當(dāng)主線程退出時,守護線程也會被終止。
  • start():啟動線程。
  • join(timeout):等待線程執(zhí)行完成,可選地設(shè)置超時時間。
  • run():線程的執(zhí)行入口點,在線程啟動時被調(diào)用。
  • sleep(secs):線程休眠指定的秒數(shù)。

9、線程間通信

線程間通信是指在多線程編程中,多個線程之間進行數(shù)據(jù)傳遞和共享的過程。線程間通信的目的是實現(xiàn)線程之間的協(xié)作和數(shù)據(jù)交換,以完成復(fù)雜的任務(wù)。在Python中,可以使用 queue 模塊提供的隊列來實現(xiàn)線程安全的數(shù)據(jù)傳遞。

queue 模塊提供了幾種隊列類型,常用的有以下三種:

Queue(先進先出隊列)

Queue 是最常用的線程安全隊列,它使用先進先出(FIFO)的方式存儲和獲取數(shù)據(jù)。多個線程可以安全地將數(shù)據(jù)放入隊列中,并從隊列中獲取數(shù)據(jù)。Queue 類提供了以下常用方法:

  • put(item[, block[, timeout]]):將數(shù)據(jù)放入隊列,可指定是否阻塞和超時時間。
  • get([block[, timeout]]):從隊列中獲取數(shù)據(jù),可指定是否阻塞和超時時間。
  • empty():判斷隊列是否為空。
  • full():判斷隊列是否已滿。
  • qsize():返回隊列中的元素數(shù)量。
import queue
 
# 創(chuàng)建隊列對象
q = queue.Queue()
 
# 線程函數(shù) A
def thread_function_a():
    while True:
        item = q.get()
        # 處理數(shù)據(jù)
 
# 線程函數(shù) B
def thread_function_b():
    while True:
        # 產(chǎn)生數(shù)據(jù)
        q.put(item)

在上述示例中,線程函數(shù) A從隊列中獲取數(shù)據(jù)并進行處理,線程函數(shù) B產(chǎn)生數(shù)據(jù)并放入隊列中,兩個線程通過隊列進行數(shù)據(jù)交換。

LifoQueue(后進先出隊列)

LifoQueue 是一種后進先出(LIFO)的隊列類型,與 Queue 不同的是,它的獲取順序與放入順序相反。其他方法與 Queue 類相同。

import queue
 
# 創(chuàng)建后進先出隊列對象
q = queue.LifoQueue()

后進先出隊列適用于某些特定的場景,例如需要按照相反的順序處理數(shù)據(jù)。

PriorityQueue(優(yōu)先級隊列)

PriorityQueue 是一種根據(jù)優(yōu)先級排序的隊列類型,可以為隊列中的每個元素指定一個優(yōu)先級。優(yōu)先級高的元素先被獲取。元素的優(yōu)先級可以是數(shù)字、元組或自定義對象。其他方法與 Queue 類相同。

import queue
 
# 創(chuàng)建優(yōu)先級隊列對象
q = queue.PriorityQueue()

優(yōu)先級隊列適用于需要根據(jù)優(yōu)先級順序處理數(shù)據(jù)的場景。

10、線程池

線程池是一種用于管理和復(fù)用線程的機制,可以有效地管理大量線程的生命周期,并提供簡化的接口來提交和管理任務(wù)。在Python中,可以使用 concurrent.futures 模塊中的 ThreadPoolExecutor 類來創(chuàng)建線程池。

線程池的特點

  • 線程復(fù)用:線程池中的線程可以被重復(fù)使用,避免了線程頻繁創(chuàng)建和銷毀的開銷。
  • 線程管理:線程池負責(zé)管理線程的生命周期,包括線程的創(chuàng)建、銷毀和回收。
  • 并發(fā)控制:線程池可以限制并發(fā)執(zhí)行的線程數(shù)量,防止系統(tǒng)資源被過度占用。
  • 異步提交:線程池提供了異步提交任務(wù)的方法,可以在后臺執(zhí)行任務(wù)并返回結(jié)果。

創(chuàng)建線程池

可以使用 ThreadPoolExecutor 類來創(chuàng)建線程池??梢灾付ň€程池的大小(可同時執(zhí)行的線程數(shù)量)和其他相關(guān)參數(shù)。

from concurrent.futures import ThreadPoolExecutor
 
# 創(chuàng)建線程池
pool = ThreadPoolExecutor(max_workers=5)

在上述示例中,創(chuàng)建了一個最大同時執(zhí)行 5 個線程的線程池。

提交任務(wù)

可以使用線程池的 submit() 方法提交任務(wù),該方法會返回一個 Future 對象,用于獲取任務(wù)的執(zhí)行結(jié)果。

# 定義任務(wù)函數(shù)
def task_function():
    # 任務(wù)邏輯
 
# 提交任務(wù)到線程池
future = pool.submit(task_function)

在上述示例中,將任務(wù)函數(shù) task_function 提交到線程池,并獲得了一個 Future 對象。

獲取任務(wù)結(jié)果

可以使用 Future 對象的 result() 方法來獲取任務(wù)的執(zhí)行結(jié)果。如果任務(wù)尚未完成,result() 方法將會阻塞直到任務(wù)完成并返回結(jié)果。

# 獲取任務(wù)結(jié)果
result = future.result()

關(guān)閉線程池

在使用完線程池后,應(yīng)該調(diào)用 shutdown() 方法來關(guān)閉線程池。關(guān)閉線程池后,將不再接受新的任務(wù)提交,并且會等待所有已提交的任務(wù)執(zhí)行完畢后再退出。

# 關(guān)閉線程池
pool.shutdown()

以上就是Python使用thread模塊實現(xiàn)多線程的操作的詳細內(nèi)容,更多關(guān)于Python thread多線程的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 8個Python中可復(fù)用函數(shù)的最佳實踐分享

    8個Python中可復(fù)用函數(shù)的最佳實踐分享

    在Python編程中,編寫可復(fù)用的函數(shù)是提高代碼質(zhì)量和開發(fā)效率的關(guān)鍵,本文將介紹8種最佳實踐,并提供豐富的示例代碼,希望可以幫助大家編寫高質(zhì)量的可復(fù)用函數(shù)
    2023-12-12
  • Python自定義元類的實例講解

    Python自定義元類的實例講解

    在本篇文章里小編給大家整理的是一篇關(guān)于Python自定義元類的實例講解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-03-03
  • 正則給header的冒號兩邊參數(shù)添加單引號(Python請求用)

    正則給header的冒號兩邊參數(shù)添加單引號(Python請求用)

    這篇文章主要介紹了正則給header的冒號兩邊參數(shù)添加單引號(Python請求用)的相關(guān)知識,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-08-08
  • Python實現(xiàn)敲擊木魚積累功德小項目

    Python實現(xiàn)敲擊木魚積累功德小項目

    最近大家都很流行用手機敲擊電子木魚積累功德,這在很多短視頻中也常常見到。本文將用Python實現(xiàn)這一效果,感興趣的小伙伴可以了解一下
    2022-11-11
  • python 監(jiān)控logcat關(guān)鍵字功能

    python 監(jiān)控logcat關(guān)鍵字功能

    這篇文章主要介紹了python 監(jiān)控logcat關(guān)鍵字功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • 基于Python實現(xiàn)加強版煙花

    基于Python實現(xiàn)加強版煙花

    這篇文章主要為大家詳細介紹了如何利用Python制作一個加強版煙花景,文中的示例代碼講解詳細,對我們學(xué)習(xí)Python有一定幫助,需要的可以參考一下
    2022-02-02
  • 使用python實現(xiàn)多維數(shù)據(jù)降維操作

    使用python實現(xiàn)多維數(shù)據(jù)降維操作

    今天小編就為大家分享一篇使用python實現(xiàn)多維數(shù)據(jù)降維操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • Python?實現(xiàn)多表和工作簿合并及一表按列拆分

    Python?實現(xiàn)多表和工作簿合并及一表按列拆分

    這篇文章主要介紹了Python?實現(xiàn)多表和工作簿合并及一表按列拆分,文章圍繞主題展開詳細的資料介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • selenium+python實現(xiàn)基本自動化測試的示例代碼

    selenium+python實現(xiàn)基本自動化測試的示例代碼

    這篇文章主要介紹了selenium+python實現(xiàn)基本自動化測試的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Appium+python自動化怎么查看程序所占端口號和IP

    Appium+python自動化怎么查看程序所占端口號和IP

    這篇文章主要介紹了Appium+python自動化怎么查看程序所占端口號和IP,本文以FQ工具 Lantern 為例,通過圖文并茂的形式給大家介紹的非常詳細,需要的朋友可以參考下
    2019-06-06

最新評論