我正在尝试使用ThreadPool来加速我的代码。
输入是一个包含大约80000个元素的字典,每个元素都是一个由25个元素组成的列表。通过处理和组合每个列表中的元素,我必须为字典中的每个元素生成一个输出列表。
所有的列表都可以独立分析,所以这个设置应该很容易并行。
下面是我用于pool.map的基本设置:
from multiprocessing.dummy import Pool as ThreadPool
pool = ThreadPool(NUM_THREADS)
output = pool.map(thread_compute, iterable_list)
pool.close()
pool.join我很快意识到,方法1将无法工作,因为它是全局变量input_dict,尽管它从未为写操作进行访问(因此应该是线程安全的),但它受到GIL (链接1,链接2)的保护--在尝试从独立线程中安全地访问Python对象时,这是一种全局强制的锁。
input_dict相同的元素的列表,其中每个条目都是一个包含25个条目的列表。这个列表不是一个全局变量,每个线程都应该能够访问一个元素(一个25项列表),而不需要任何开销,这是由于GIL.in --主项= list(input_dict.items()) iterable_list = [itemsi for i in range(len( items ))] ##确保内容正确地断言(len(Iterable_list) == len(input_dict))在xrange中(len(input_dict.keys():assert(iterable_listi == input_dict[input_ )]dict.keys()i]) # thread_compute函数def thread_compute(list_of_25_i):#调用函数processed_list = do_stuff_function(list_of_25_i)返回processed_list以下是1、2、4和16个线程的执行时间:
1: Done, (t=36.6810s).
2: Done, (t=46.5550s).
4: Done, (t=48.2722s).
16: Done, (t=48.9660s).为什么添加线程会导致时间的增加?我确信这个问题可以从多线程中受益,并且认为添加线程的开销不能单独负责增加。
发布于 2016-09-27 15:53:54
如果您的do_stuff_function是CPU绑定的,那么在多个线程中运行它不会有帮助,因为GIL只允许一次执行一个线程。
在Python中,解决这个问题的方法是使用多个进程,只需替换
from multiprocessing.dummy import Pool使用
from multiprocessing import Pool发布于 2016-09-27 15:57:49
尝试使用Pool (文档),因为它使用processes而不是threads。
concurrent,而不是parallel,这基本上意味着解释器将在执行多个线程之间非常快地切换,而在执行一个线程时,锁定所有其他线程的解释器,从而给人以并行运行操作的印象。但是,考虑到您发布的处理时间适中,生成进程所需的时间可能会对总体性能产生负面影响。
https://stackoverflow.com/questions/39728974
复制相似问题