假设我有一个名为dog的类:
class dog():
def __init__(self, name, age):
self.name = name
self.age = age
self.fleas = []现在假设我有一份名单,
names = ["bob", "joe", "dave"] 我创建了一个列表,执行以下操作:
dogs = [dog(name, index) for index, name in enumerate(names)] # Creates a list "dogs" that has 3 dog classes in it, named bob, joe, david, with ages 0, 1, 2 respectively.现在我有了一本跳鼠字典,
global_fleas = {"bob":[flea_43], "joe":[flea_20], "dave":[flea_3]}还有一些单独的方法flea_mod()可以修改这个字典,以便将每只狗的跳鼠数更改为某个随机数,如flea_50。在这本词典中,每只狗只有一只跳鼠。
通过执行以下操作,我可以将global_fleas中的跳鼠附加到其对应的狗上:
def dirty_dog(dog):
dog.fleas.append(global_fleas[dog.name])这是最重要的。我想多处理这个循环。这就是我现在所拥有的:
while True:
flea_mod() # This randomizes the flea_number for each dog in the global_flea dictionary
pool = multiprocessing.Pool(processes=len(dogs))
[pool.apply_async(dirty_dog, dog) for dog in dogs]
pool.close()
pool.join()因此,问题是每个狗对象并不是在每次循环运行时都保留其跳鼠列表。我希望在每个循环的末尾保留每只狗的跳鼠列表,这样在两次循环之后,每只狗就会有两只跳鼠,依此类推。有什么想法吗?我猜我得做点泡菜了。
发布于 2013-05-06 08:20:56
在可能的情况下,多处理文档建议不要使用共享状态,但您可以使用托管字典来实现您的目标:
http://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes
(请参阅基于服务器的管理器部分。)
这样,您可以根据您的核心逻辑更改单个托管对象,处理节点将看到更新后的版本。你必须在你的代码中尝试一下,看看最好的共享设置是什么(如果有的话)。
发布于 2013-05-06 08:20:07
J.F·塞巴斯蒂安是对的。您在循环中看不到突变的原因是它们发生在另一个过程中。您似乎不太熟悉流程;您应该考虑使用learning more about them。
您希望从池中获取结果,并将其复制到您当地的狗。要做到这一点,一种方法是修改您的循环,使其如下所示:
pool = multiprocessing.Pool(processes=some_number_of_processes)
while True:
flea_mod()
results = [pool.appy_async(dirty_dog, dog) for dog in dogs]
for result, dog in zip(results, dogs):
# I assume that dirty_dog returns the updated dog.
dog.update(result.get(timeout=some_positive_number_of_seconds))需要注意的几件事:
some_number_of_processes可以是< len(dogs)!每个过程都会产生一些开销;因此,存在一个收益递减点。通常情况下,高估一点要比低估好。然而,严重高估是很容易避免的,除非你真的很懒。如果你使用的是Python3.2或更高版本,并且dirty_dog不受CPU限制(例如,经常接触磁盘),那么可以考虑使用ThreadPoolExecutor;这样,修改就不需要被复制,因为线程将在相同的对象上操作,而不是复制。
发布于 2013-05-06 08:49:42
除非dirty_dog()执行一些此处未显示的冗长计算,否则多处理不会提高性能(所有好处都将通过来回复制数据来消耗)。
import multiprocessing as mp
def dirty_dog(i):
dog = dogs[i]
dog.fleas.append(global_fleas[dog.name])
dogs[i] = dog
def init(global_fleas_, dogs_):
global global_fleas, dogs
global_fleas, dogs = global_fleas_, dogs_
if __name__=="__main__":
manager = mp.Manager()
dogs = manager.list(dogs)
pool = mp.Pool(initializer=init, initargs=[global_fleas, dogs])
for _ in range(3):
flea_mod()
pool.map(dirty_dog, range(len(dogs)))
pool.close()
pool.join()https://stackoverflow.com/questions/16390070
复制相似问题