Python:多线程不能提高运行效率

2024-04-26 13:21:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试编写简单的多线程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

我的问题是:我的代码中的瓶颈是什么,为什么我看不到任何改进?你知道吗

有关我的电脑的一些数据:

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

Tags: ofpathimagesrcimgosthreadnum
3条回答

问题来自于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是线程模块周围的包装器,它允许您在使用处理池时与线程池进行交互。你知道吗

您应该只使用具有可用cpu核数的多处理。您也没有使用队列,因此资源池正在执行相同的工作。您需要向代码中添加一个队列。你知道吗

Filling a queue and managing multiprocessing in python

怪吉尔。你知道吗

Python有一种称为GIL的机制,即全局解释器锁。它基本上是一个互斥锁,防止本机线程同时执行Python字节码。必须这样做,因为Python(至少是CPython)的内存管理不是线程安全的。你知道吗

换句话说,GIL将阻止您同时运行多个线程。基本上,一次只运行一个线程。多线程(Multi-threading)在利用多个CPU核的意义上,更像是Python中的幻觉。你知道吗

幸运的是,有办法解决这个问题。不过,从资源角度看,这要贵一点。您可以使用多处理代替。Python通过multiprocessing模块对此有很好的支持。这样,就可以实现并行性[1]。你知道吗

您可能会问,为什么多处理不受GIL限制的影响。答案很简单。程序的每个新进程都有一个不同的Python解释器实例(我认为有一个更好的说法)。这意味着每个进程都有自己的GIL。因此,进程不是由GIL管理的,而是由操作系统本身管理的。这为您提供了并行性[2]。你知道吗


参考文献

相关问题 更多 >