亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我可以在 python 中應用多線程來執行計算密集型任務嗎?

我可以在 python 中應用多線程來執行計算密集型任務嗎?

小唯快跑啊 2023-09-19 14:32:27
更新:為了節省您的時間,我直接在這里給出答案。如果你使用純Python編寫代碼, Python不能同時利用多CPU核心。但是Python在調用一些用C編寫的函數或包時可以同時利用多核,例如Numpy等。我聽說“ Python中的多線程并不是真正的多線程,因為有GIL ”。我還聽說“ Python多線程可以處理IO密集型任務而不是計算密集型任務,因為只有一個線程同時運行”。但我的經歷讓我重新思考這個問題。我的經驗表明,即使對于計算密集型任務,Python 多線程也可以幾乎很快地加速計算。(在使用多線程之前,運行以下程序花費了 300 秒,使用多線程之后,花費了 100 秒。)python下圖顯示,使用CPythonpackage編譯器創建了5個線程threading,幾乎cpu cores都是100%的百分比。我認為截圖可以證明5個cpu核心同時運行。那么有人可以給我解釋嗎?我可以在 python 中應用多線程來執行計算密集型任務嗎?或者在Python中可以同時運行多線程/核心嗎?我的代碼:import threadingimport timeimport numpy as npfrom scipy import interpolatenumber_list = list(range(10))def image_interpolation():    while True:        number = None        with threading.Lock():            if len(number_list):                number = number_list.pop()        if number is not None:            # Make a fake image - you can use yours.            image = np.ones((20000, 20000))            # Make your orig array (skipping the extra dimensions).            orig = np.random.rand(12800, 16000)            # Make its coordinates; x is horizontal.            x = np.linspace(0, image.shape[1], orig.shape[1])            y = np.linspace(0, image.shape[0], orig.shape[0])            # Make the interpolator function.            f = interpolate.interp2d(x, y, orig, kind='linear')        else:            return 1workers=5thd_list = []t1 = time.time()for i in range(workers):    thd = threading.Thread(target=image_interpolation)    thd.start()    thd_list.append(thd)for thd in thd_list:    thd.join()t2 = time.time()print("total time cost with multithreading: " + str(t2-t1))number_list = list(range(10))for i in range(10):    image_interpolation()t3 = time.time()print("total time cost without multithreading: " + str(t3-t2))輸出是:total time cost with multithreading: 112.71922039985657total time cost without multithreading: 328.45561170578003
查看完整描述

2 回答

?
慕森王

TA貢獻1777條經驗 獲得超3個贊

正如您提到的,Python 有一個“全局解釋器鎖”(GIL),可以防止Python 代碼的兩個線程同時運行。多線程可以加速 IO 密集型任務的原因是 Python 在偵聽網絡套接字或等待磁盤讀取時釋放 GIL。因此,GIL 不會阻止計算機同時完成兩批工作,它會阻止同一 Python 進程中的兩個 Python 線程同時運行。

在您的示例中,您使用 numpy 和 scipy。這些主要是用 C 編寫的,并利用用 C/Fortran/Assembly 編寫的庫(BLAS、LAPACK 等)。當您對 numpy 數組執行操作時,類似于監聽套接字,因為GIL 被釋放。當 GIL 被釋放并且 numpy 數組操作被調用時,numpy 開始決定如何執行工作。如果需要,它可以生成其他線程或進程,并且它調用的 BLAS 子例程可能會生成其他線程。如果您想從源代碼編譯 numpy,則可以在構建時準確配置是否/如何完成此操作。

因此,總而言之,您已經找到了規則的例外。如果您僅使用純 Python 函數重復該實驗,您將得到完全不同的結果。


查看完整回答
反對 回復 2023-09-19
?
四季花海

TA貢獻1811條經驗 獲得超5個贊

Python 線程是真正的線程,只是解釋器中不能同時存在兩個線程(這就是 GIL 的含義)。代碼的本機部分可以很好地并行運行,而不會在多個線程上發生爭用,只有當深入解釋器時,它們才必須在彼此之間進行序列化。

僅將所有 CPU 核心加載到 100% 的事實并不能證明您正在“高效”使用機器。您需要確保 CPU 使用率不是由上下文切換引起的。

如果您切換到多處理而不是線程(它們非常相似),則不必雙重猜測,但是在線程之間傳遞時必須對有效負載進行封送。

所以無論如何都需要測量一切。


查看完整回答
反對 回復 2023-09-19
  • 2 回答
  • 0 關注
  • 133 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號