簡體   English   中英

Python:多線程不會改善運行時

[英]Python : multithread doesn't improve run time

我正在嘗試編寫簡單的多線程python腳本:

from multiprocessing.dummy import Pool as ThreadPool

def resize_img_folder_multithreaded(img_fldr_src,img_fldr_dst,max_num_of_thread):

    images = glob.glob(img_fldr_src+'/*.'+img_file_extension)
    pool = ThreadPool(max_num_of_thread) 

    pool.starmap(resize_img,zip(images,itertools.repeat(img_fldr_dst)))
    # close the pool and wait for the work to finish 
    pool.close() 
    pool.join() 


def resize_img(img_path_src,img_fldr_dest):
    #print("about to resize image=",img_path_src)
    image = io.imread(img_path_src)         
    image = transform.resize(image, [300,300])
    io.imsave(os.path.join(img_fldr_dest,os.path.basename(img_path_src)),image)      
    label = img_path_src[:-4] + '.xml'
    if copyLabels is True and os.path.exists(label) is True :
        copyfile(label,os.path.join(img_fldr_dest,os.path.basename(label)))

將參數max_num_of_thread設置為[1 ... 10]中的任何數字都不會改善我的運行時間( for 60 images it stays around 30 sec ), max_num_of_thread = 10我的PC卡住了

我的問題是:我的代碼中的瓶頸是什么,為什么我看不到任何改進?

關於我的電腦的一些數據:

python -V
Python 3.6.4 :: Anaconda, Inc.


cat /proc/cpuinfo | grep 'processor' | wc -l
4

cat /proc/meminfo 
MemTotal:        8075960 kB
MemFree:         3943796 kB
MemAvailable:    4560308 kB

cat /etc/*release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=17.10

歸咎於GIL。

Python有這種稱為GIL的機制,即全局解釋器鎖。 它基本上是一個互斥鎖,可以防止本機線程一次執行Python字節碼。 必須這樣做,因為Python(至少是CPython)內存管理不是線程安全的。

換句話說,GIL將阻止您同時運行多個線程。 基本上,您一次運行一個線程。 在利用多個CPU核心的意義上,多線程更像是Python中的錯覺。

幸運的是,有一種方法可以解決這個問題。 雖然它在資源方面有點貴。 您可以使用多處理。 Python通過multiprocessing模塊為此提供了出色的支持。 這樣,您就可以實現並行性[1]

您可能會問為什么多重處理不受GIL限制的影響。 答案很簡單。 程序的每個新進程都有一個不同的實例(我認為這是一個更好的詞)Python解釋器。 這意味着每個進程都有自己的GIL。 因此,這些流程不是由GIL管理,而是由操作系統本身管理。 這為您提供了並行性[2]


參考

問題來自Global Interpreter Lock或GIL。 GIL一次只允許一個線程運行,所以如果你想進行並行計算,請使用Processing.Pool

import multiprocessing

pool = multiprocessing.Pool(max_num_of_process)  # Use number of core as max number

multiprocessing.dummy是線程模塊的一個包裝器,它允許您與使用Processing Pool的線程池進行交互。

您應該只對可用的cpu核心數使用多處理。 您也沒有使用隊列,因此資源池正在執行相同的工作。 您需要為代碼添加隊列。

填充隊列並在python中管理多處理

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM