【发布时间】:2020-05-20 02:54:15
【问题描述】:
因此,我查看了多处理模块的文档以及此处提出的其他问题,但似乎没有一个与我的情况相似,因此我提出了一个新问题。
为简单起见,我有一段代码如下:
# simple dataframe of some users and their properties.
data = {'userId': [1, 2, 3, 4],
'property': [12, 11, 13, 43]}
df = pd.DataFrame.from_dict(data)
# a function that generates permutations of the above users, in the form of a list of lists
# such as [[1,2,3,4], [2,1,3,4], [2,3,4,1], [2,4,1,3]]
user_perm = generate_permutations(nr_perm=4)
# a function that computes some relation between users
def comp_rel(df, permutation, user_dict):
df1 = df.userId.isin(permutation[0])
df2 = df.userId.isin(permutation[1])
user_dict[permutation[0]] += permutation[1]
return user_dict
# and finally a loop:
user_dict = defaultdict(int)
for permutation in user_perm:
user_dict = comp_rel(df, permutation, user_dict)
我知道这段代码现在没有什么意义(如果有的话),但我只是写了一个小例子,它与我正在处理的实际代码的结构很接近。 user_dict 最终应该包含 userIds 和一些值。
我有实际的代码,它工作正常,给出了正确的 dict 和所有内容,但是......它在单个线程上运行。而且它非常缓慢,请记住我还有另外 15 个线程完全免费。
我的问题是,如何使用 python 的 multiprocessing 模块来更改最后一个 for 循环,并能够在所有可用的线程/内核上运行?看了文档,不是很容易理解。
编辑:我正在尝试将池用作:
p = multiprocessing.Pool(multiprocessing.cpu_count())
p.map(comp_rel(df, permutation, user_dict), user_perm)
p.close()
p.join()
但是这会中断,因为我正在使用该行:
user_dict = comp_rel(df, permutation, user_dict)
在初始代码中,我不知道池完成后应该如何合并这些字典。
【问题讨论】:
-
你肯定需要了解GIL。
-
@OlvinRoght 我知道有一些锁,但这也说明:但是,一些扩展模块,无论是标准的还是第三方的,都被设计为在执行计算密集型任务时释放 GIL例如压缩或散列。多处理似乎就是这样一个模块。
-
-
@GPhilo,据我所知,我的机器有 4 个内核,每个内核有 4 个线程。如果我使用 htop,我会看到 16 个空闲的“线程”。我们说的是线程还是内核?
-
多处理模块中的示例展示了如何做到这一点:docs.python.org/3/library/… 您可以使用池来触发
comp_rel的每个调用。由于您要启动多个 python 进程,因此 GIL 不会成为问题。
标签: python python-3.x dictionary multiprocessing