我创建了一个小代码片段(原始代码要大得多),它调用一个创建对象的函数,但是在一个进程池中:
import multiprocessing
class TestClass(object):
pass
def func():
obj = TestClass()
cpname = multiprocessing.current_process().name
print "{0}, Address: {1}".format(cpname, str(obj))
pool = multiprocessing.Pool(2)
results = [pool.apply_async(func) for _ in range(2)]
for res in results:
res.get()
pool.close()
pool.join()
当我运行此代码时,我得到以下输出:
PoolWorker-1, Address: <__main__.TestClass object at 0x7f05d3fdad50>
PoolWorker-2, Address: <__main__.TestClass object at 0x7f05d3fdad50>
我不明白的是,为什么对象具有相同的地址,即使它们位于不同的进程中?
如何确保每个进程都创建自己的对象?
非常感谢你的帮助。
答案 0 :(得分:3)
当您.ChartArea(chartArea => chartArea.Background("transparent").Height(600))
进行多处理时,它会复制您的流程。内存分配器和父进程中的所有地址将被复制到子进程中。因此,下一次分配很可能具有相同的地址。
您可以验证它们实际上是单独的对象,如下所示:
fork()
答案 1 :(得分:2)
对象不同,不同的进程使用不同的virtual address space,不同进程中的相同地址指向不同的内存区域。
如果你改变你的例子,你会发现返回的对象是不同的:
import multiprocessing
class TestClass(object):
pass
def func():
obj = TestClass()
cpname = multiprocessing.current_process().name
print "{0}, Address: {1}".format(cpname, str(obj))
return obj
pool = multiprocessing.Pool(2)
results = [pool.apply_async(func) for _ in range(2)]
results = [res.get() for res in results]
pool.close()
pool.join()
print results
答案 2 :(得分:1)
似乎您可能正在使用Linux-ish系统,其中通过fork()
创建新流程。在这种情况下,您应该期望地址之间的大量重叠。这并不意味着您的obj
个实例占用相同的物理内存 - 只是它们共享相同的虚拟(进程本地)地址。
更多信息:
What happens to address's, values, and pointers after a fork()