[英]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
对象使用Semaphore
和Condition
,它们都依赖于SemLock
对象提供的锁定行为。 反过来,它包装了一个_multiprocessing.SemLock
对象,该对象在c中实现并依赖于sem_open
(POSIX)或CreateSemaphore
(Windows)。
这些是c函数,可以访问由操作系统本身管理的共享资源 - 在本例中为命名信号量。 它们可以在线程或进程之间共享; 操作系统负责一切。 会发生什么,当创建一个新的信号量时,会给它一个句柄 。 然后,当创建需要访问该信号量的新进程时,会给它一个句柄副本。 然后它将该句柄传递给sem_open
或CreateSemapohre
,操作系统为新进程提供对原始信号量的访问权限。
所以内存被共享,但它被作为操作系统的内置的同步原语支持部分共享。 换句话说,在这种情况下,您不需要打开新进程来管理共享内存; 操作系统接管该任务。 但这只是可能的,因为Event
不需要比信号量更复杂的工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.