可以使用 threadpool
来实现多线程并行。
示例
我想用多线程求一个数列的和,可以如下操作:
import threadpool
def func(dic, c):
dic['count'] += c
if __name__=="__main__":
d = dict()
d['count'] = 0
l = [1, 2, 3]
pool = threadpool.ThreadPool(len(l)) # 成立线程池
params = [([d, x], None) for x in l] # 拼接 func 的参数
requests = threadpool.makeRequests(func, params) #
[pool.putRequest(req) for req in requests]
pool.wait()
print(f'dic={d}')
输出:
dic={'count': 6}
函数
makeRequests()
函数原型:makeRequests(callable_, args_list, callback=None, exc_callback=_handle_thread_exception)
可以很方便地创建多个工作请求(调用函数相同、参数不同)。
其中,
callable_
为需要调用的函数名args_list
是一个 list,每一个元素包含了一次调用的所有参数。每个元素的格式二选一:
1、一个单一的、非元组的参数。
2、一个二维元组,存放着一个 list 和一个 dict,list 按照顺序存放了函数的参数,dict 按照 key 存放了函数的参数。list 和 dict 有一个即可,另外一个可以为 None。
例子中 args_list
的值为
params = [([d, x], None) for x in l]
params
的元素就是一个二元元组,其中 dict 为 None,list 为二维数组,按顺序存放着 dic 和 c 的值。
也可以这样写:
params = [(None, {'dic':d, 'c':x}) for x in l]
params
的元素也是一个二元元组,其中 list 为 None,dict 按 key 存放着 dic 和 c 的值。
这两种赋值的效果是等价的。
putRequest()
函数原型为 putRequest(self, request, block=True, timeout=None)
将工作请求放入到工作队列中,并执行。
wait()
阻塞,直到线程池中所有的线程都结束。
内存共享
多线程之间是可以共享任何内存的,比如例子中的 dic 就被共享了,因此可以对其进行累加。
如果是多进程,则不可以共享内存,如果需要共享,需要其他的手段才可以,参照python技巧——使用Pool实现多进程并行.