繁体   English   中英

Python multiprocessing.Process对象的行为类似于在另一个进程中保存对对象的引用。 为什么?

[英]Python multiprocessing.Process object behaves like it would hold a reference to an object in another process. Why?

import multiprocessing as mp

def delay_one_second(event):
    print 'in SECONDARY process, preparing to wait for 1 second'
    event.wait(1)
    print 'in the SECONDARY process, preparing to raise the event'
    event.set()

if __name__=='__main__':
    evt = mp.Event()
    print 'preparing to wait 10 seconds in the PRIMARY process'
    mp.Process(target = delay_one_second, args=(evt,)).start()
    evt.wait(10)
    print 'PRIMARY process, waking up'

这段代码(在cmd.exe中使用“python module.py”命令从模块内部运行得很好)会产生令人惊讶的结果。

主要过程显然只在醒来之前等待1秒钟。 为此,这意味着辅助进程具有对主进程中对象的引用。

怎么会这样? 我期望必须使用multiprocessing.Manager()来在进程之间共享对象,但这怎么可能呢?

我的意思是进程不是线程,它们不应该使用相同的内存空间。 任何人都有任何想法在这里发生了什么?

文档说多处理模块遵循线程API。 我的猜测是它使用类似'fork'的机制。 如果您分叉一个线程,您的操作系统将创建当前进程的副本。 这意味着它复制堆和堆栈,包括所有变量和全局变量,这就是你所看到的。

如果将下面的函数传递给新进程,您可以自己查看。

def print_globals():
    print globals()

简短的回答是共享内存不是由单独的进程管理的; 它由操作系统本身管理。

如果您花一些时间浏览multiprocessing源,可以看到它是如何工作的。 您将看到Event对象使用SemaphoreCondition ,它们都依赖于SemLock对象提供的锁定行为。 反过来,它包装了一个_multiprocessing.SemLock对象,该对象在c中实现并依赖于sem_open (POSIX)或CreateSemaphore (Windows)。

这些是c函数,可以访问由操作系统本身管理的共享资源 - 在本例中为命名信号量。 它们可以在线程进程之间共享; 操作系统负责一切。 会发生什么,当创建一个新的信号量时,会给它一个句柄 然后,当创建需要访问该信号量的新进程时,会给它一个句柄副本。 然后它将该句柄传递给sem_openCreateSemapohre ,操作系统为新进程提供对原始信号量的访问权限。

所以内存共享,但它被作为操作系统的内置的同步原语支持部分共享。 换句话说,在这种情况下,您不需要打开新进程来管理共享内存; 操作系统接管该任务。 但这只是可能的,因为Event不需要比信号量更复杂的工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM