国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

python多進(jìn)程與多線程

這篇具有很好參考價(jià)值的文章主要介紹了python多進(jìn)程與多線程。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1 Python多線程

1.1 GIL 全局解釋器鎖

其他語(yǔ)言,CPU是多核時(shí)是支持多個(gè)線程同時(shí)執(zhí)行。但在Python中,無(wú)論是單核還是多核,同時(shí)只能由一個(gè)線程在執(zhí)行。其根源是GIL的存在。GIL的全稱(chēng)是Global Interpreter Lock(全局解釋器鎖),來(lái)源是Python設(shè)計(jì)之初的考慮,為了數(shù)據(jù)安全所做的決定。某個(gè)線程想要執(zhí)行,必須先拿到GIL,我們可以把GIL看作是“通行證”,并且在一個(gè)Python進(jìn)程中,GIL只有一個(gè)。拿不到通行證的線程,就不允許進(jìn)入CPU執(zhí)行。

GIL與python解釋器有關(guān),目前常用的Python的解釋器有:

  • CPython:CPython是用C語(yǔ)言實(shí)現(xiàn)的Python解釋器。 作為官方實(shí)現(xiàn),它是最廣泛使用的Python解釋器。
  • PyPy:PyPy是用RPython實(shí)現(xiàn)的解釋器。RPython是Python的子集, 具有靜態(tài)類(lèi)型。這個(gè)解釋器的特點(diǎn)是即時(shí)編譯,支持多重后端(C, CLI, JVM)。PyPy旨在提高性能,同時(shí)保持最大兼容性(參考CPython的實(shí)現(xiàn))。
  • Jython:Jython是一個(gè)將Python代碼編譯成Java字節(jié)碼的實(shí)現(xiàn),運(yùn)行在JVM (Java Virtual Machine) 上。另外,它可以像是用Python模塊一樣,導(dǎo)入并使用任何Java類(lèi)。

GIL只在CPython中才有,而在PyPy和Jython中是沒(méi)有GIL的。

每次釋放GIL鎖,線程進(jìn)行鎖競(jìng)爭(zhēng)、切換線程,會(huì)消耗資源。這就導(dǎo)致打印線程執(zhí)行時(shí)長(zhǎng),會(huì)發(fā)現(xiàn)耗時(shí)更長(zhǎng)的原因。

并且由于GIL鎖存在,Python里一個(gè)進(jìn)程永遠(yuǎn)只能同時(shí)執(zhí)行一個(gè)線程(拿到GIL的線程才能執(zhí)行),這就是為什么在多核CPU上,Python 的多線程效率并不高的根本原因。

1.2 創(chuàng)建多線程

Python提供兩個(gè)模塊進(jìn)行多線程的操作,分別是threadthreading,前者是比較低級(jí)的模塊,用于更底層的操作,一般應(yīng)用級(jí)別的開(kāi)發(fā)不常用。

Python還提供了線程池函數(shù)ThreadPoolExecutor,它是 concurrent.futures 模塊中的一個(gè)類(lèi),其主要作用是為多線程執(zhí)行提供高級(jí)別的接口。

以下是關(guān)于 ThreadPoolExecutor 的一些重要特性:

  • 線程池管理: ThreadPoolExecutor 可以創(chuàng)建一個(gè)線程池,并自動(dòng)管理其中的線程。當(dāng)你提交一個(gè)任務(wù)給 ThreadPoolExecutor 時(shí),它會(huì)選擇一個(gè)空閑的線程去執(zhí)行這個(gè)任務(wù)。如果所有線程都在忙碌,則任務(wù)會(huì)等待直到有線程變?yōu)榭臻e。
  • 任務(wù)返回值處理: 當(dāng)你提交一個(gè)任務(wù)給 ThreadPoolExecutor 時(shí),它會(huì)立即返回一個(gè) Future 對(duì)象。通過(guò)這個(gè) Future 對(duì)象,你可以查詢(xún)?nèi)蝿?wù)的狀態(tài)(是否完成,是否成功),獲取任務(wù)的返回值,或者等待任務(wù)完成。
  • 任務(wù)異常處理: 如果任務(wù)拋出了一個(gè)異常,ThreadPoolExecutor 將不會(huì)立即拋出這個(gè)異常。相反,當(dāng)你試圖通過(guò) Future 對(duì)象獲取任務(wù)的結(jié)果時(shí),異常才會(huì)被拋出。這使得你可以更好地控制何時(shí)處理這些異常。
  • 并行和異步執(zhí)行: ThreadPoolExecutor 允許你在多個(gè)線程中并行地執(zhí)行多個(gè)任務(wù),從而實(shí)現(xiàn)異步操作。這對(duì)于IO密集型任務(wù)尤其有益,比如網(wǎng)絡(luò)請(qǐng)求或文件讀寫(xiě)等。
  • 資源清理: 當(dāng) ThreadPoolExecutor 離開(kāi) with 語(yǔ)句塊時(shí),它會(huì)等待所有的任務(wù)都完成,然后釋放所有的資源。這包括結(jié)束所有的線程,釋放所有的鎖,等等。這種機(jī)制可以保證資源被正確地清理。

總的來(lái)說(shuō),ThreadPoolExecutor 提供了一種高級(jí)、方便、安全的方式來(lái)進(jìn)行多線程編程。

  • 方法1:直接使用threading.Thread()
import threading

# 這是你要多線程執(zhí)行的函數(shù)
def worker(num):
    """thread worker function"""
    print('Worker: %s' % num)

# 創(chuàng)建線程列表
threads = []

# 啟動(dòng)5個(gè)線程來(lái)運(yùn)行worker函數(shù)
for i in range(5):
    t = threading.Thread(target=worker, args=(i,))
    threads.append(t)
    t.start()

# 等待所有線程完成
for thread in threads:
    thread.join()

print("All threads completed.")
  • 方法2:繼承threading.Thread來(lái)自定義線程類(lèi),重寫(xiě)run方法
import threading
 
class MyThread(threading.Thread):
    def __init__(self, n):
        super(MyThread, self).__init__()  # 重構(gòu)run函數(shù)必須要寫(xiě)
        self.n = n
 
    def run(self):
        print("current task:", n)
 
if __name__ == "__main__":
    t1 = MyThread("thread 1")
    t2 = MyThread("thread 2")
 
    t1.start()
    t2.start()
1.3 join函數(shù)

在Python中,join()方法用于等待線程執(zhí)行完畢。它使主線程等待其他子線程完成任務(wù)后再繼續(xù)執(zhí)行。join()方法被調(diào)用時(shí),主線程會(huì)阻塞,直到調(diào)用它的線程執(zhí)行完畢。

以下是一個(gè)例子,演示了join()方法的作用:

import threading
import time

def task():
    print("Thread started")
    time.sleep(2)  # 模擬線程執(zhí)行耗時(shí)操作
    print("Thread finished")

if __name__ == "__main__":
    t = threading.Thread(target=task)
    t.start()
    print("Main thread continues executing")
    t.join()  # 等待線程t執(zhí)行完畢
    print("Main thread resumed after thread t finished")

在上面的例子中,我們創(chuàng)建了一個(gè)子線程t,并在主線程中啟動(dòng)它。子線程執(zhí)行task()函數(shù),在函數(shù)中模擬了一個(gè)耗時(shí)操作time.sleep(2)。主線程在啟動(dòng)子線程后會(huì)立即繼續(xù)執(zhí)行,并打印出"Main thread continues executing"。

然而,我們?cè)谥骶€程的下一個(gè)步驟中調(diào)用了t.join()。這意味著主線程會(huì)等待子線程執(zhí)行完畢后再繼續(xù)執(zhí)行。在本例中,主線程會(huì)阻塞,直到子線程執(zhí)行完畢。

當(dāng)子線程完成任務(wù)后,會(huì)打印出"Thread finished"。此時(shí)主線程會(huì)繼續(xù)執(zhí)行,并打印出"Main thread resumed after thread t finished"。

通過(guò)調(diào)用t.join(),我們確保了主線程等待子線程完成后再繼續(xù)執(zhí)行,這對(duì)于需要線程之間協(xié)調(diào)和同步的情況非常有用。

1.4 線程同步與互斥鎖

線程之間數(shù)據(jù)是共享的。當(dāng)多個(gè)線程對(duì)某一個(gè)共享數(shù)據(jù)進(jìn)行操作時(shí),就需要考慮到線程安全問(wèn)題。在Python的threading模塊中,Lock類(lèi)是用于創(chuàng)建鎖對(duì)象的工具,它允許線程之間進(jìn)行同步。

下面是一個(gè)使用Lock類(lèi)的例子:

import threading

shared_resource = 0  	 # 共享資源
lock = threading.Lock()  # 創(chuàng)建一個(gè)鎖對(duì)象

def increment():
    global shared_resource
    for _ in range(100000):
        lock.acquire()  # 獲取鎖
        shared_resource += 1
        lock.release()  # 釋放鎖

if __name__ == "__main__":
    threads = []
    for _ in range(5):
        t = threading.Thread(target=increment)
        threads.append(t)
        t.start()

    for t in threads:
        t.join()

    print("Final value of shared_resource:", shared_resource)

在上面的例子中,我們創(chuàng)建了一個(gè)共享資源shared_resource,它的初始值為0。我們還創(chuàng)建了一個(gè)Lock對(duì)象lock

然后,我們定義了一個(gè)increment函數(shù),它通過(guò)循環(huán)多次增加共享資源的值。在每次增加之前,我們使用lock.acquire()獲取鎖,以確保當(dāng)前線程獨(dú)占對(duì)共享資源的訪問(wèn)。完成增加后,我們使用lock.release()釋放鎖。

在主程序中,我們創(chuàng)建了5個(gè)線程,并將它們添加到一個(gè)線程列表中。然后,我們啟動(dòng)這些線程,并等待它們執(zhí)行完畢。

最后,我們打印出最終的shared_resource的值。由于使用了鎖來(lái)保護(hù)共享資源的訪問(wèn),每個(gè)線程都會(huì)依次獲取鎖并增加共享資源的值,從而保證了最終結(jié)果的正確性。

通過(guò)使用Lock類(lèi),我們可以在多線程環(huán)境中實(shí)現(xiàn)對(duì)共享資源的安全訪問(wèn)和修改,避免了競(jìng)態(tài)條件(race condition)的發(fā)生。

1.4.1 競(jìng)態(tài)條件

競(jìng)態(tài)條件(Race Condition)是指多個(gè)并發(fā)執(zhí)行的線程或進(jìn)程在訪問(wèn)共享資源或執(zhí)行操作時(shí)的不確定性和不可預(yù)測(cè)性。競(jìng)態(tài)條件會(huì)導(dǎo)致程序在多線程環(huán)境下產(chǎn)生錯(cuò)誤的結(jié)果或出現(xiàn)異常行為。

競(jìng)態(tài)條件發(fā)生的原因是由于多個(gè)線程或進(jìn)程在沒(méi)有正確同步的情況下同時(shí)訪問(wèn)共享資源或執(zhí)行操作,且其執(zhí)行順序無(wú)法確定。具體來(lái)說(shuō),當(dāng)多個(gè)線程或進(jìn)程對(duì)共享資源進(jìn)行讀寫(xiě)操作時(shí),其執(zhí)行順序可能導(dǎo)致互相干擾、相互覆蓋或產(chǎn)生不一致的結(jié)果。

以下是一個(gè)簡(jiǎn)單的競(jìng)態(tài)條件示例:

import threading

counter = 0

def increment():
    global counter
    for _ in range(100000):
        counter += 1

if __name__ == "__main__":
    threads = []
    for _ in range(5):
        t = threading.Thread(target=increment)
        threads.append(t)
        t.start()

    for t in threads:
        t.join()

    print("Final value of counter:", counter)

在上述示例中,我們創(chuàng)建了一個(gè)全局計(jì)數(shù)器counter并定義了一個(gè)increment函數(shù),該函數(shù)使用循環(huán)遞增計(jì)數(shù)器的值。我們創(chuàng)建了5個(gè)線程,每個(gè)線程都會(huì)調(diào)用increment函數(shù)。

由于多個(gè)線程同時(shí)對(duì)counter進(jìn)行寫(xiě)操作(遞增),競(jìng)態(tài)條件就會(huì)出現(xiàn)。因?yàn)榫€程之間的執(zhí)行順序是不確定的,可能會(huì)發(fā)生如下情況:

  • 線程 A 讀取counter的值為 0。
  • 線程 B 讀取counter的值為 0。
  • 線程 A 遞增counter的值為 1。
  • 線程 B 遞增counter的值為 1。
  • 最終的結(jié)果是counter的值為 1,而不是預(yù)期的 2。

這個(gè)示例展示了競(jìng)態(tài)條件的問(wèn)題,多個(gè)線程并發(fā)地修改共享資源導(dǎo)致最終結(jié)果的不確定性。

1.5 可重入鎖(遞歸鎖)

為了滿足在同一線程中多次請(qǐng)求同一資源的需求,Python提供了可重入鎖(RLock)。RLock內(nèi)部維護(hù)著一個(gè)Lock和一個(gè)counter變量,counter記錄了acquire 的次數(shù),從而使得資源可以被多次require。直到一個(gè)線程所有的acquire都被release,其他的線程才能獲得資源。具體用法如下:

1.6 python多線程相比其他語(yǔ)言的優(yōu)勢(shì)

關(guān)于Python多線程與其他編程語(yǔ)言相比的優(yōu)勢(shì),以下幾點(diǎn)可能值得注意:

  • 簡(jiǎn)潔性:Python的語(yǔ)法簡(jiǎn)潔明了。對(duì)于多線程編程來(lái)說(shuō),Python提供了 threading 和 concurrent.futures 等模塊,使得開(kāi)發(fā)者可以很容易地創(chuàng)建和管理線程。
  • 高級(jí)特性:Python提供了許多高級(jí)工具來(lái)處理多線程編程中的復(fù)雜問(wèn)題,例如隊(duì)列(queue),事件(event),鎖(lock)和條件變量(condition)等。
  • 異常處理:Python的線程庫(kù)允許在子線程中捕獲并傳播異常,這樣主線程可以知道任務(wù)是否成功完成。
  • 豐富的庫(kù)支持:Python有大量的第三方庫(kù),很多庫(kù)都支持多線程或者異步操作,例如 requests 庫(kù)就可以非常容易地配合 concurrent.futures 來(lái)進(jìn)行并發(fā)的HTTP請(qǐng)求。

然而,需要注意的是,Python的多線程并不適合所有場(chǎng)景。由于Python的全局解釋器鎖(GIL)的存在,Python的多線程在計(jì)算密集型任務(wù)上并不能實(shí)現(xiàn)真正意義上的并行執(zhí)行 (即同一時(shí)間點(diǎn),有多個(gè)線程同時(shí)被多個(gè)CPU核心執(zhí)行)。如果你的程序是計(jì)算密集型的,那么使用多進(jìn)程(multiprocessing 模塊)或者其它能夠避免 GIL 問(wèn)題的方法可能會(huì)更加有效。

1.6 queue

Python 的 queue 模塊提供了一種線程安全的隊(duì)列數(shù)據(jù)結(jié)構(gòu),用于在多線程環(huán)境中進(jìn)行線程間通信和數(shù)據(jù)傳遞。使用 queue 可以解決多線程編程中的許多常見(jiàn)問(wèn)題,以下是它的主要作用:

  • 線程間通信: 隊(duì)列通常用于在生產(chǎn)者和消費(fèi)者線程之間進(jìn)行通信。生產(chǎn)者線程可以生成數(shù)據(jù)并將其放入隊(duì)列,而消費(fèi)者線程可以從隊(duì)列中獲取并處理數(shù)據(jù)。這種模式可以有效地對(duì)多線程進(jìn)行解耦。
  • 線程同步: 隊(duì)列還可以用于同步多個(gè)線程的工作。例如,一個(gè)線程可能需要等待另一個(gè)線程完成特定任務(wù)后才能繼續(xù)執(zhí)行。這可以通過(guò)在第一個(gè)線程中獲取隊(duì)列項(xiàng)來(lái)實(shí)現(xiàn),其中隊(duì)列項(xiàng)由第二個(gè)線程在完成任務(wù)后添加。
  • 數(shù)據(jù)安全性: Python 的 queue 是線程安全的,也就是說(shuō),無(wú)論何時(shí)只有一個(gè)線程可以讀取或?qū)懭腙?duì)列。這意味著你不必自己管理鎖或其他低級(jí)同步機(jī)制,降低了出錯(cuò)的可能性。
  • 限制內(nèi)存使用: 隊(duì)列可以設(shè)置最大長(zhǎng)度(即隊(duì)列能容納的元素?cái)?shù)量)。這對(duì)于控制內(nèi)存使用非常有用,特別是當(dāng)生產(chǎn)者線程比消費(fèi)者線程更快時(shí),可以防止隊(duì)列中堆積過(guò)多的元素導(dǎo)致內(nèi)存耗盡。
  • 任務(wù)調(diào)度: 通過(guò)分別使用優(yōu)先級(jí)隊(duì)列、LIFO隊(duì)列(即棧)和FIFO隊(duì)列(默認(rèn)),可以實(shí)現(xiàn)各種類(lèi)型的任務(wù)調(diào)度策略。

因此,Python 的 queue 在多線程編程中起著至關(guān)重要的作用,尤其在需要在線程之間安全地共享數(shù)據(jù)或同步線程操作時(shí)。

1.7 condition

Python中的Condition對(duì)象是threading模塊中的同步原語(yǔ)之一。它通常用于管理那些需要等待某些條件成立才能執(zhí)行的線程,從而允許某些線程在滿足特定條件時(shí)喚醒其他線程。

以下是關(guān)于Condition對(duì)象的一些重要特性:

  • 鎖定和解鎖: 和Lock或RLock對(duì)象一樣,Condition也支持acquire()和release()方法來(lái)控制對(duì)共享資源的訪問(wèn)。
  • 等待條件: Condition對(duì)象提供了一個(gè)wait()方法,使得線程可以等待特定的條件成立。當(dāng)調(diào)用wait()方法時(shí),線程會(huì)釋放鎖并進(jìn)入睡眠狀態(tài),等待被其他線程喚醒。
  • 喚醒線程: Condition對(duì)象有兩個(gè)方法,notify()和notify_all(),用于喚醒等待該Condition的線程。notify(n)喚醒n個(gè)等待的線程,notify_all()則喚醒所有等待的線程。

以下是一個(gè)簡(jiǎn)單的例子,說(shuō)明了如何使用Condition對(duì)象:

import threading

# 創(chuàng)建一個(gè) Condition 對(duì)象
cond = threading.Condition()

def consumer():
    with cond:
        print("Consumer: Waiting for condition")
        cond.wait()
        print("Consumer: Condition met")

def producer():
    with cond:
        print("Producer: Changing the condition")
        # 發(fā)信號(hào)通知等待的線程
        cond.notifyAll()

t1 = threading.Thread(target=consumer)
t2 = threading.Thread(target=producer)

t1.start()
t2.start()

在這個(gè)例子中,消費(fèi)者線程首先啟動(dòng)并等待條件達(dá)成。生產(chǎn)者線程改變條件,并通過(guò)調(diào)用cond.notifyAll()喚醒消費(fèi)者線程。

2 Python 多進(jìn)程

2.1 創(chuàng)建多進(jìn)程

Python要進(jìn)行多進(jìn)程操作,需要用到muiltprocessing庫(kù),其中的Process類(lèi)跟threading模塊的Thread類(lèi)很相似。

  • 方法1:直接使用Process, 代碼如下:
from multiprocessing import Process  
 
def show(name):
    print("Process name is " + name)
 
if __name__ == "__main__": 
    proc = Process(target=show, args=('subprocess',))  
    proc.start()  
    proc.join()
  • 方法2:繼承Process來(lái)自定義進(jìn)程類(lèi),重寫(xiě)run方法, 代碼如下:
from multiprocessing import Process
import time
 
class MyProcess(Process):
    def __init__(self, name):
        super(MyProcess, self).__init__()
        self.name = name
 
    def run(self):
        print('process name :' + str(self.name))
        time.sleep(1)
 
if __name__ == '__main__':
    for i in range(3):
        p = MyProcess(i)
        p.start()
    for i in range(3):
        p.join()
2.2 多進(jìn)程通信

進(jìn)程之間不共享數(shù)據(jù)的。如果進(jìn)程之間需要進(jìn)行通信,則要用到Queue模塊或者Pipe模塊來(lái)實(shí)現(xiàn)。

2.2.1 Queue

Queue是多進(jìn)程安全的隊(duì)列,可以實(shí)現(xiàn)多進(jìn)程之間的數(shù)據(jù)傳遞。它主要有兩個(gè)函數(shù)put和get。

put() 用以插入數(shù)據(jù)到隊(duì)列中,put還有兩個(gè)可選參數(shù):blocked 和timeout。如果blocked為 True(默認(rèn)值),并且timeout為正值,該方法會(huì)阻塞timeout指定的時(shí)間,直到該隊(duì)列有剩余的空間。如果超時(shí),會(huì)拋出 Queue.Full異常。如果blocked為False,但該Queue已滿,會(huì)立即拋出Queue.Full異常。

get()可以從隊(duì)列讀取并且刪除一個(gè)元素。同樣get有兩個(gè)可選參數(shù):blocked和timeout。如果blocked為T(mén)rue(默認(rèn)值),并且 timeout為正值,那么在等待時(shí)間內(nèi)沒(méi)有取到任何元素,會(huì)拋出Queue.Empty異常。如果blocked為False,有兩種情況存在,如果Queue有一個(gè)值可用,則立即返回該值,否則,如果隊(duì)列為空,則立即拋出Queue.Empty異常。

具體用法如下:

from multiprocessing import Process, Queue
 
def put(queue):
    queue.put('Queue 用法')
 
if __name__ == '__main__':
    queue = Queue()
    pro = Process(target=put, args=(queue,))
    pro.start()
    print(queue.get())   
    pro.join()
2.2.2 Pipe

Pipe的本質(zhì)是進(jìn)程之間的用管道數(shù)據(jù)傳遞,而不是數(shù)據(jù)共享,這和socket有點(diǎn)像。pipe() 返回兩個(gè)連接對(duì)象分別表示管道的兩端,每端都有send()和recv()函數(shù)。如果兩個(gè)進(jìn)程試圖在同一時(shí)間的同一端進(jìn)行讀取和寫(xiě)入那么,這可能會(huì)損壞管道中的數(shù)據(jù),具體用法如下:

from multiprocessing import Process, Pipe
 
def show(conn):
    conn.send('Pipe 用法')
    conn.close()
 
if __name__ == '__main__':
    parent_conn, child_conn = Pipe() 
    pro = Process(target=show, args=(child_conn,))
    pro.start()
    print(parent_conn.recv())   
    pro.join()
2.3 進(jìn)程池

創(chuàng)建多個(gè)進(jìn)程,我們不用傻傻地一個(gè)個(gè)去創(chuàng)建。我們可以使用Pool模塊來(lái)搞定。Pool 常用的方法如下:

python多進(jìn)程與多線程

具體用法見(jiàn)示例代碼:

#coding: utf-8
import multiprocessing
import time
 
def func(msg):
    print("msg:", msg)
    time.sleep(3)
    print("end")
 
if __name__ == "__main__":
    # 維持執(zhí)行的進(jìn)程總數(shù)為processes,當(dāng)一個(gè)進(jìn)程執(zhí)行完畢后會(huì)添加新的進(jìn)程進(jìn)去
    pool = multiprocessing.Pool(processes = 3)
    for i in range(5):
        msg = "hello %d" %(i)
        # 非阻塞式,子進(jìn)程不影響主進(jìn)程的執(zhí)行,會(huì)直接運(yùn)行到 pool.join()
        pool.apply_async(func, (msg, ))   
 
        # 阻塞式,先執(zhí)行完子進(jìn)程,再執(zhí)行主進(jìn)程
        # pool.apply(func, (msg, ))   
 
    print("Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~")
    # 調(diào)用join之前,先調(diào)用close函數(shù),否則會(huì)出錯(cuò)。
    pool.close()
    # 執(zhí)行完close后不會(huì)有新的進(jìn)程加入到pool,join函數(shù)等待所有子進(jìn)程結(jié)束
    pool.join()   
    print("Sub-process(es) done.")

如上,進(jìn)程池Pool被創(chuàng)建出來(lái)后,即使實(shí)際需要?jiǎng)?chuàng)建的進(jìn)程數(shù)遠(yuǎn)遠(yuǎn)大于進(jìn)程池的最大上限,p.apply_async(test)代碼依舊會(huì)不停的執(zhí)行,并不會(huì)停下等待;相當(dāng)于向進(jìn)程池提交了10個(gè)請(qǐng)求,會(huì)被放到一個(gè)隊(duì)列中;
當(dāng)執(zhí)行完p1 = Pool(5)這條代碼后,5條進(jìn)程已經(jīng)被創(chuàng)建出來(lái)了,只是還沒(méi)有為他們各自分配任務(wù),也就是說(shuō),無(wú)論有多少任務(wù),實(shí)際的進(jìn)程數(shù)只有5條,計(jì)算機(jī)每次最多5條進(jìn)程并行。
當(dāng)Pool中有進(jìn)程任務(wù)執(zhí)行完畢后,這條進(jìn)程資源會(huì)被釋放,pool會(huì)按先進(jìn)先出的原則取出一個(gè)新的請(qǐng)求給空閑的進(jìn)程繼續(xù)執(zhí)行;
當(dāng)Pool所有的進(jìn)程任務(wù)完成后,會(huì)產(chǎn)生5個(gè)僵尸進(jìn)程,如果主線程不結(jié)束,系統(tǒng)不會(huì)自動(dòng)回收資源,需要調(diào)用join函數(shù)去回收。
join函數(shù)是主進(jìn)程等待子進(jìn)程結(jié)束回收系統(tǒng)資源的,如果沒(méi)有join,主程序退出后不管子進(jìn)程有沒(méi)有結(jié)束都會(huì)被強(qiáng)制殺死;
創(chuàng)建Pool池時(shí),如果不指定進(jìn)程最大數(shù)量,默認(rèn)創(chuàng)建的進(jìn)程數(shù)為系統(tǒng)的內(nèi)核數(shù)量.

3 選擇多線程還是多進(jìn)程?

在這個(gè)問(wèn)題上,首先要看下你的程序是屬于哪種類(lèi)型的。一般分為兩種:CPU密集型和I/O密集型。

  • CPU 密集型:程序比較偏重于計(jì)算,需要經(jīng)常使用CPU來(lái)運(yùn)算。例如科學(xué)計(jì)算的程序,機(jī)器學(xué)習(xí)的程序等。
  • I/O 密集型:顧名思義就是程序需要頻繁進(jìn)行輸入輸出操作。爬蟲(chóng)程序就是典型的I/O密集型程序。

如果程序是屬于CPU密集型,建議使用多進(jìn)程。而多線程就更適合應(yīng)用于I/O密集型程序。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-454957.html

到了這里,關(guān)于python多進(jìn)程與多線程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • python開(kāi)發(fā)環(huán)境的安裝,PyCharm+python解釋器

    python開(kāi)發(fā)環(huán)境的安裝,PyCharm+python解釋器

    以下是Windows下的安裝,Linux以及其他操作系統(tǒng)下的安裝請(qǐng)類(lèi)比參照! PyCharm+python解釋器 下載鏈接: https://download.csdn.net/download/qq_30255657/87693274 也可以自己?jiǎn)为?dú)下載安裝 下載 下載地址:http://www.jetbrains.com/pycharm/download/#section=windows 安裝 安裝路徑 ,自己定義修改 設(shè)置 , 請(qǐng)參照

    2023年04月16日
    瀏覽(23)
  • python編程——編譯器與解釋器

    python編程——編譯器與解釋器

    作者: Insist-- 個(gè)人主頁(yè): insist--個(gè)人主頁(yè) 本文專(zhuān)欄: python專(zhuān)欄 專(zhuān)欄介紹: 本專(zhuān)欄為 免費(fèi) 專(zhuān)欄,并且會(huì)持續(xù)更新python基礎(chǔ)知識(shí),歡迎各位訂閱關(guān)注。 目錄 一、編譯器與解釋器的介紹 二、編譯器與解釋器的區(qū)別 三、python編譯器與解釋器種類(lèi) 1、Brython 2、winPython 3、Pyjs 四、

    2024年02月07日
    瀏覽(32)
  • 國(guó)內(nèi)鏡像安裝Python解釋器及擴(kuò)展包

    官網(wǎng)(下載速度很慢):Welcome to Python.org 淘寶鏡像(推薦):CNPM Binaries Mirror (npmmirror.com) 前往淘寶鏡像站,選擇版本,這里以Python3.10.10為例。 如果是64位的系統(tǒng),點(diǎn)擊 python-3.10.10-amd64.exe ,等待下載完成。 運(yùn)行下載好的 python-3.10.10-amd64.exe ,將 Add python.exe to PATH 勾選上,將

    2024年02月10日
    瀏覽(25)
  • PyCharm無(wú)法找到Python解釋器,如何解決?

    當(dāng)你在PyCharm中設(shè)置項(xiàng)目或運(yùn)行Python腳本時(shí),有時(shí)會(huì)遇到PyCharm無(wú)法找到Python解釋器的問(wèn)題。這可能是由于配置錯(cuò)誤、環(huán)境變量設(shè)置問(wèn)題或者PyCharm本身的一些問(wèn)題所導(dǎo)致的。解決此問(wèn)題的方法包括檢查PyCharm的設(shè)置、配置解釋器路徑和檢查Python安裝等。下面將介紹一些常見(jiàn)的解決

    2024年02月04日
    瀏覽(23)
  • pycharm—配置python解釋器【2023最新版】

    pycharm—配置python解釋器【2023最新版】

    嗨嗨,大家好啊,我是小曼~ 剛?cè)腴T(mén)python的伙伴們,一開(kāi)始也會(huì)很多的問(wèn)題。今天來(lái)給大家分享一下python新手必須學(xué)會(huì)的技巧 : pycharm中配置python解釋器 依次點(diǎn)擊file - settings 打開(kāi)設(shè)置 依次點(diǎn)擊 project:Pythonproject → Python interpreter 依次選擇,點(diǎn)擊設(shè)置。 左邊 第一個(gè)是選擇Py

    2024年02月08日
    瀏覽(100)
  • Ubuntu離線或在線安裝Python解釋器

    這里以安裝Python3.5.7為例。 首先進(jìn)入官網(wǎng),下載Python-3.5.7.tgz,或者使用以下命令下載(需要聯(lián)網(wǎng)): 下載完成后,使用以下命令進(jìn)行解壓縮: 解壓完成后,會(huì)生成一個(gè)Python-3.5.7目錄,進(jìn)入該目錄,執(zhí)行配置命令: 配置完成后,編譯: 編譯完成后,安裝: 到這一步就已經(jīng)完

    2024年02月09日
    瀏覽(27)
  • 如何在VSCode中添加Python解釋器并安裝Python庫(kù)

    如何在VSCode中添加Python解釋器并安裝Python庫(kù)

    孟莉蘋(píng),女,西安工程大學(xué)電子信息學(xué)院,2021級(jí)碩士研究生,張宏偉人工智能課題組 研究方向:機(jī)器視覺(jué)與人工智能 電子郵件:2425613875@qq.com 喬冠華,女,西安工程大學(xué)電子信息學(xué)院,2020級(jí)碩士研究生,張宏偉人工智能課題組。 研究方向:機(jī)器視覺(jué)與人工智能。 電子郵件

    2024年02月03日
    瀏覽(31)
  • Aanconda安裝python以及Pycharm配置Python解釋器詳細(xì)教程

    Aanconda安裝python以及Pycharm配置Python解釋器詳細(xì)教程

    Anaconda即是管理python的一個(gè)平臺(tái),可以利用Anaconda創(chuàng)建虛擬環(huán)境,更好的管理自己的項(xiàng)目以及第三方庫(kù)。安裝了這之后不需要再下載python解釋器!??! anaconda下載鏈接?? 1. 在 d盤(pán) 目錄下新建一個(gè)文件夾 , 命名為Anaconda ,這個(gè)目錄很重要,一定要記得他,以后的虛擬環(huán)境就在

    2024年04月11日
    瀏覽(105)
  • macOS本地python環(huán)境/vscode/導(dǎo)入python包/設(shè)置python解釋器

    macOS本地python環(huán)境/vscode/導(dǎo)入python包/設(shè)置python解釋器

    查看macbook本地是否有python環(huán)境 輸入 python 或者 python3 ,退出python環(huán)境使用 exit() ,別忘了括號(hào) 沒(méi)有的話去官網(wǎng)安裝https://www.python.org/ 2. 安裝vscode 官網(wǎng)https://code.visualstudio.com/ 3. 安裝插件 點(diǎn)擊左邊的“插件”按鈕,安裝這三個(gè)插件 4. 設(shè)置python解釋器 點(diǎn)擊左下角的“設(shè)置”按鈕

    2024年02月09日
    瀏覽(16)
  • python解釋器及開(kāi)發(fā)工具安裝-windows版

    python解釋器及開(kāi)發(fā)工具安裝-windows版

    1.python解釋器安裝 1 需要到官網(wǎng)下載安裝python解釋器 步驟1:官網(wǎng)鏈接:https://www.python.org/downloads/,選擇Downloads下Windows版本 步驟2:版本較多,選擇適合的Windows版本進(jìn)行下載,如下: 2 解釋器安裝 步驟4:下載好后點(diǎn)擊雙擊exe文件安裝即可(安裝位置可自選,安裝時(shí)可勾選添加

    2024年02月15日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包