[英]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核心數使用多處理。 您也沒有使用隊列,因此資源池正在執行相同的工作。 您需要為代碼添加隊列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.