欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python并發(fā)執(zhí)行的幾種實(shí)現(xiàn)方法

 更新時(shí)間:2024年08月05日 09:47:45   作者:solihawk  
在Python中多線程是實(shí)現(xiàn)并發(fā)的一種方式,多線程可以讓程序在同一時(shí)間內(nèi)進(jìn)行多個(gè)任務(wù),從而提高程序的效率和執(zhí)行速度,這篇文章主要給大家介紹了關(guān)于Python并發(fā)執(zhí)行的幾種實(shí)現(xiàn)方法,需要的朋友可以參考下

1、Python中并發(fā)執(zhí)行實(shí)現(xiàn)方法

1.1 Python中并發(fā)執(zhí)行實(shí)現(xiàn)

在Python中,有幾種主要的并發(fā)執(zhí)行實(shí)現(xiàn)方法,包括多線程、多進(jìn)程和異步編程。

1.1.1 多線程(Threading)

Python標(biāo)準(zhǔn)庫(kù)中的threading模塊支持多線程編程。然而,由于Python的全局解釋器鎖(GIL),Python的多線程在CPU密集型任務(wù)上并不能實(shí)現(xiàn)真正的并行執(zhí)行。但在I/O密集型任務(wù)(如網(wǎng)絡(luò)請(qǐng)求、文件讀寫(xiě)等)上,多線程仍然可以顯著提升性能。

import threading  
  
def worker():  
    print("This is a thread running the worker function.")  
  
# 創(chuàng)建線程對(duì)象  
threads = []  
for _ in range(5):  
    t = threading.Thread(target=worker)  
    threads.append(t)  
    t.start()  
  
# 等待所有線程完成  
for t in threads:  
    t.join()

1.1.2 多進(jìn)程(Multiprocessing)

Python的multiprocessing模塊支持多進(jìn)程編程,可以充分利用多核CPU的資源。每個(gè)進(jìn)程都有自己獨(dú)立的Python解釋器,因此不受GIL的限制。多進(jìn)程適用于CPU密集型任務(wù)。

import multiprocessing  
  
def worker():  
    print("This is a process running the worker function.")  
  
if __name__ == "__main__":  
    processes = []  
    for _ in range(5):  
        p = multiprocessing.Process(target=worker)  
        processes.append(p)  
        p.start()  
  
    # 等待所有進(jìn)程完成  
    for p in processes:  
        p.join()

1.1.3 異步編程(Asyncio)

Python 3.5引入了asyncio模塊,支持異步編程。異步編程可以在單線程內(nèi)實(shí)現(xiàn)非阻塞的I/O操作,提高程序的響應(yīng)速度和吞吐量。它特別適用于處理大量的并發(fā)I/O操作,如網(wǎng)絡(luò)請(qǐng)求。

import asyncio  
  
async def worker():  
    print("This is an async task running the worker function.")  
  
# 創(chuàng)建事件循環(huán)  
loop = asyncio.get_event_loop()  
tasks = []  
for _ in range(5):  
    task = loop.create_task(worker())  
    tasks.append(task)  
  
# 執(zhí)行所有任務(wù)  
loop.run_until_complete(asyncio.wait(tasks))  
loop.close()

注意:異步編程與多線程和多進(jìn)程編程有所不同,它更多的是一種編程模型,而不是簡(jiǎn)單地創(chuàng)建多個(gè)執(zhí)行單元。異步編程需要理解并適應(yīng)其特有的編程模式和概念,如協(xié)程、事件循環(huán)等。

1.2 Python中多進(jìn)程和多線程的區(qū)別

在Python中,multiprocessing和threading模塊都用于實(shí)現(xiàn)并發(fā)執(zhí)行,但它們?cè)诘讓訖C(jī)制、使用場(chǎng)景和性能特點(diǎn)上有顯著的區(qū)別。

1.2.1 Multiprocessing多進(jìn)程

Multiprocessing模塊允許創(chuàng)建多個(gè)進(jìn)程來(lái)執(zhí)行Python代碼。每個(gè)進(jìn)程都有自己獨(dú)立的內(nèi)存空間和解釋器實(shí)例,因此它們之間不共享全局變量(除非通過(guò)特定的機(jī)制,如multiprocessing.Manager或multiprocessing.Value、multiprocessing.Array等)。這使得multiprocessing非常適合于計(jì)算密集型任務(wù),因?yàn)樗梢猿浞掷枚嗪薈PU并行處理任務(wù)。

由于每個(gè)進(jìn)程都有自己獨(dú)立的Python解釋器,進(jìn)程間通信(IPC)通常比線程間通信(通過(guò)共享內(nèi)存)要慢得多,并且需要顯式的IPC機(jī)制,如管道(Pipe)、隊(duì)列(Queue)、共享內(nèi)存(SharedMemory)等。

1.2.2 Threading多線程

Threading模塊允許創(chuàng)建多個(gè)線程來(lái)執(zhí)行Python代碼。線程共享同一個(gè)進(jìn)程的內(nèi)存空間,因此它們可以直接訪問(wèn)全局變量和大多數(shù)Python對(duì)象。這使得線程間通信相對(duì)簡(jiǎn)單,因?yàn)樗鼈兛梢灾苯幼x寫(xiě)共享的內(nèi)存。

然而,由于Python的全局解釋器鎖(GIL)的存在,同一時(shí)間內(nèi)只有一個(gè)線程可以執(zhí)行Python代碼。這意味著即使是多線程,CPU密集型任務(wù)的執(zhí)行速度也可能不會(huì)顯著提高。因此,threading模塊在Python中通常更適用于IO密集型任務(wù),如網(wǎng)絡(luò)請(qǐng)求、文件讀寫(xiě)等,這些任務(wù)通??梢栽谝粋€(gè)線程等待IO操作完成時(shí)讓另一個(gè)線程繼續(xù)執(zhí)行。

1.2.3 多進(jìn)程和多線程特性對(duì)比

  • 資源共享:
    • 多線程:在多線程中,所有線程共享同一個(gè)進(jìn)程的地址空間,這意味著它們可以訪問(wèn)相同的變量和內(nèi)存區(qū)域。因此,多線程間的數(shù)據(jù)共享和通信相對(duì)簡(jiǎn)單,但也容易引發(fā)數(shù)據(jù)同步和一致性的問(wèn)題,如競(jìng)態(tài)條件。
    • 多進(jìn)程:每個(gè)進(jìn)程都有自己獨(dú)立的地址空間,這意味著它們無(wú)法直接共享數(shù)據(jù)。進(jìn)程間的通信需要通過(guò)特殊的機(jī)制來(lái)實(shí)現(xiàn),如管道、消息隊(duì)列、共享內(nèi)存或套接字等。雖然進(jìn)程間通信相對(duì)復(fù)雜,但它避免了多線程中的數(shù)據(jù)同步問(wèn)題。
  • 全局解釋器鎖(GIL):
    • 多線程:由于Python的全局解釋器鎖(GIL)的存在,Python的多線程在CPU密集型任務(wù)上并不能實(shí)現(xiàn)真正的并行執(zhí)行。GIL確保任何時(shí)候只有一個(gè)線程在執(zhí)行Python字節(jié)碼。因此,對(duì)于計(jì)算密集型任務(wù),多線程并不能帶來(lái)性能提升。
    • 多進(jìn)程:多進(jìn)程不受GIL的限制,每個(gè)進(jìn)程都有自己獨(dú)立的Python解釋器,因此可以充分利用多核CPU的資源,實(shí)現(xiàn)真正的并行執(zhí)行。
  • 性能開(kāi)銷(xiāo):
    • 多線程:線程創(chuàng)建和銷(xiāo)毀的開(kāi)銷(xiāo)相對(duì)較小,因?yàn)榫€程共享進(jìn)程的內(nèi)存空間,無(wú)需復(fù)制數(shù)據(jù)。因此,對(duì)于需要頻繁創(chuàng)建和銷(xiāo)毀線程的應(yīng)用,多線程可能是一個(gè)更好的選擇。
    • 多進(jìn)程:進(jìn)程創(chuàng)建和銷(xiāo)毀的開(kāi)銷(xiāo)相對(duì)較大,因?yàn)槊總€(gè)進(jìn)程都需要獨(dú)立的內(nèi)存空間和系統(tǒng)資源。此外,進(jìn)程間通信也需要額外的開(kāi)銷(xiāo)。因此,對(duì)于需要大量進(jìn)程的應(yīng)用,需要謹(jǐn)慎考慮性能問(wèn)題。
  • 穩(wěn)定性:
    • 多線程:由于線程共享數(shù)據(jù),如果一個(gè)線程崩潰,可能會(huì)導(dǎo)致整個(gè)進(jìn)程崩潰。
    • 多進(jìn)程:每個(gè)進(jìn)程都是獨(dú)立的,一個(gè)進(jìn)程的崩潰不會(huì)影響其他進(jìn)程。因此,多進(jìn)程在穩(wěn)定性方面可能更有優(yōu)勢(shì)。
  • 適用場(chǎng)景:
    • 多線程:適用于I/O密集型任務(wù),如網(wǎng)絡(luò)請(qǐng)求、文件讀寫(xiě)等。在這些場(chǎng)景下,線程大部分時(shí)間都在等待I/O操作完成,因此可以充分利用多線程的優(yōu)勢(shì)。
    • 多進(jìn)程:適用于CPU密集型任務(wù),如科學(xué)計(jì)算、圖像處理等。在這些場(chǎng)景下,多進(jìn)程可以充分利用多核CPU的資源,實(shí)現(xiàn)性能提升。

總之,選擇使用多線程還是多進(jìn)程取決于具體的任務(wù)類(lèi)型和性能需求。在Python中,對(duì)于I/O密集型任務(wù),可以使用多線程或異步編程;對(duì)于CPU密集型任務(wù),多進(jìn)程可能是一個(gè)更好的選擇。

1.3 等待信號(hào)量實(shí)現(xiàn)并發(fā)控制

信號(hào)量是一個(gè)計(jì)數(shù)器,用于控制同時(shí)訪問(wèn)某個(gè)特定資源或資源池的線程數(shù)量。信號(hào)量有一個(gè)值,表示可用的許可數(shù)。當(dāng)線程想要訪問(wèn)資源時(shí),它必須先獲取一個(gè)許可;如果許可數(shù)大于0,則獲取成功并減1;否則,線程將阻塞等待。

import threading  

sem = threading.Semaphore(3)  # 允許三個(gè)線程同時(shí)訪問(wèn)資源  

def worker():  
    sem.acquire()  # 獲取許可  
    try:  
        # 訪問(wèn)或修改共享資源  
        print("Thread is working with the shared resource.")  
    finally:  
        sem.release()  # 釋放許可  

# 創(chuàng)建并啟動(dòng)線程...

1.3.1 基于等待信號(hào)量實(shí)現(xiàn)多進(jìn)程并發(fā)

在Python中,基于等待信號(hào)量(Semaphore)實(shí)現(xiàn)多進(jìn)程并發(fā)通常涉及到multiprocessing模塊中的Semaphore類(lèi)。信號(hào)量用于控制對(duì)共享資源的訪問(wèn),允許一定數(shù)量的進(jìn)程同時(shí)訪問(wèn)該資源。當(dāng)信號(hào)量的值大于0時(shí),進(jìn)程可以獲得一個(gè)信號(hào)量許可來(lái)訪問(wèn)資源;當(dāng)信號(hào)量的值為0時(shí),進(jìn)程將阻塞,直到有其他進(jìn)程釋放一個(gè)許可。

下面是一個(gè)簡(jiǎn)單的例子,展示了如何使用multiprocessing.Semaphore來(lái)實(shí)現(xiàn)多進(jìn)程并發(fā)訪問(wèn)共享資源:

import multiprocessing  
import time  
import random  
  
# 設(shè)置信號(hào)量的初始值,這里允許3個(gè)進(jìn)程同時(shí)訪問(wèn)共享資源  
semaphore = multiprocessing.Semaphore(3)  
  
def worker_process(process_id, semaphore):  
    # 嘗試獲取信號(hào)量許可  
    semaphore.acquire()  
    try:  
        print(f"Process {process_id} acquired semaphore and is working.")  
        # 模擬工作負(fù)載  
        time.sleep(random.random())  
        print(f"Process {process_id} finished working and releasing semaphore.")  
    finally:  
        # 無(wú)論是否發(fā)生異常,都要確保釋放信號(hào)量許可  
        semaphore.release()  
  
if __name__ == '__main__':  
    # 創(chuàng)建進(jìn)程池  
    processes = []  
    for i in range(10):  # 創(chuàng)建10個(gè)進(jìn)程  
        p = multiprocessing.Process(target=worker_process, args=(i, semaphore))  
        processes.append(p)  
        p.start()  
  
    # 等待所有進(jìn)程完成  
    for p in processes:  
        p.join()  
  
    print("All processes have finished.")

在這個(gè)例子中創(chuàng)建了10個(gè)進(jìn)程,但是通過(guò)信號(hào)量限制了同時(shí)訪問(wèn)共享資源的進(jìn)程數(shù)最多為3個(gè)。每個(gè)進(jìn)程在工作前都會(huì)嘗試獲取信號(hào)量的許可,如果信號(hào)量的值大于0,則獲取許可并開(kāi)始工作;如果信號(hào)量的值為0,則進(jìn)程會(huì)阻塞等待,直到有其他進(jìn)程釋放許可。每個(gè)進(jìn)程完成工作后會(huì)釋放其持有的信號(hào)量許可,這樣其他等待的進(jìn)程就可以獲取許可并開(kāi)始工作。

1.3.2 基于等待信號(hào)量實(shí)現(xiàn)多線程并發(fā)

在Python中,要實(shí)現(xiàn)基于等待信號(hào)量的多線程并發(fā),可以使用threading模塊中的Semaphore類(lèi)。信號(hào)量用于控制對(duì)共享資源的并發(fā)訪問(wèn)。當(dāng)信號(hào)量的值大于0時(shí),線程可以獲得一個(gè)信號(hào)量許可來(lái)訪問(wèn)資源;當(dāng)信號(hào)量的值為0時(shí),線程將阻塞,直到其他線程釋放一個(gè)許可。

下面是一個(gè)簡(jiǎn)單的例子,展示了如何使用threading.Semaphore來(lái)實(shí)現(xiàn)多線程并發(fā)訪問(wèn)共享資源:

import threading  
import time  
import random  
  
# 設(shè)置信號(hào)量的初始值,這里允許3個(gè)線程同時(shí)訪問(wèn)共享資源  
semaphore = threading.Semaphore(3)  
  
def worker_thread(thread_id, semaphore):  
    # 嘗試獲取信號(hào)量許可  
    semaphore.acquire()  
    try:  
        print(f"Thread {thread_id} acquired semaphore and is working.")  
        # 模擬工作負(fù)載  
        time.sleep(random.random())  
        print(f"Thread {thread_id} finished working and releasing semaphore.")  
    finally:  
        # 無(wú)論是否發(fā)生異常,都要確保釋放信號(hào)量許可  
        semaphore.release()  
  
if __name__ == '__main__':  
    # 創(chuàng)建線程列表  
    threads = []  
    for i in range(10):  # 創(chuàng)建10個(gè)線程  
        t = threading.Thread(target=worker_thread, args=(i, semaphore))  
        threads.append(t)  
        t.start()  
  
    # 等待所有線程完成  
    for t in threads:  
        t.join()  
  
    print("All threads have finished.")

在這個(gè)例子中創(chuàng)建了10個(gè)線程,但是通過(guò)信號(hào)量限制了同時(shí)訪問(wèn)共享資源的線程數(shù)最多為3個(gè)。每個(gè)線程在工作前都會(huì)嘗試獲取信號(hào)量的許可,如果信號(hào)量的值大于0,則獲取許可并開(kāi)始工作;如果信號(hào)量的值為0,則線程會(huì)阻塞等待,直到有其他線程釋放許可。每個(gè)線程完成工作后會(huì)釋放其持有的信號(hào)量許可,這樣其他等待的線程就可以獲取許可并開(kāi)始工作。

總結(jié)

到此這篇關(guān)于Python并發(fā)執(zhí)行的幾種實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)Python并發(fā)執(zhí)行實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論