Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python multiprocessing.Process对象的行为就像它在另一个进程中保存对对象的引用一样。为什么?_Python_Process_Multiprocessing_Shared Memory - Fatal编程技术网

Python multiprocessing.Process对象的行为就像它在另一个进程中保存对对象的引用一样。为什么?

Python multiprocessing.Process对象的行为就像它在另一个进程中保存对对象的引用一样。为什么?,python,process,multiprocessing,shared-memory,Python,Process,Multiprocessing,Shared Memory,这段代码(在cmd.exe中使用“pythonmodule.py”命令从模块内部很好地运行)产生了一个令人惊讶的结果 主进程显然只需等待1秒就可以醒来。为了实现这一点,它意味着辅助进程对主进程中的对象有一个引用 这怎么可能?我原以为必须使用multiprocessing.Manager()在进程之间共享对象,但这怎么可能呢 我的意思是进程不是线程,它们不应该使用相同的内存空间。有人知道这里发生了什么吗?文档中说多处理模块遵循线程API。我的猜测是,它使用了一种类似于“fork”的机制。如果您分叉

这段代码(在cmd.exe中使用“pythonmodule.py”命令从模块内部很好地运行)产生了一个令人惊讶的结果

主进程显然只需等待1秒就可以醒来。为了实现这一点,它意味着辅助进程对主进程中的对象有一个引用

这怎么可能?我原以为必须使用multiprocessing.Manager()在进程之间共享对象,但这怎么可能呢


我的意思是进程不是线程,它们不应该使用相同的内存空间。有人知道这里发生了什么吗?

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

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


简而言之,共享内存不是由单独的进程管理的;它由操作系统本身管理

如果您花一些时间浏览
多处理
源代码,您可以看到这是如何工作的。您将看到一个对象使用了和,这两者都依赖于对象提供的锁定行为。这反过来又包装了一个对象,该对象是用c实现的,依赖于(POSIX)或(Windows)

这些是c函数,可以访问由操作系统本身管理的共享资源——在本例中是命名信号量。它们可以在线程或进程之间共享;操作系统负责一切。当一个新的信号量被创建时,它会被赋予一个句柄。然后,当一个需要访问该信号量的新进程被创建时,它将得到一个句柄的副本。然后它将该句柄传递给或,操作系统将新进程访问原始信号量


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

打印globals不会有多大帮助,好吧,很明显,它会给出相同的结果(很好,差不多)。打印对象的
id
会有所帮助。我做到了,但他们不一样。。。。在我看来,事件对象以某种方式映射到进程之间,因为在第二个进程中,设置了一个未pickeld事件,这与主进程中的非pickeld事件不同process@vlad-ardelean进程可以共享内存地址,但正如您所指出的,
repr(事件)的结果
实际显示内存地址不同。
Event
的这两个实例的共同点是相同的内部信号量,这使得进程之间的同步成为可能。@A.rod尽管
id(evt.\u cond)
id(evt.\u flag)
也返回不同的结果,但我知道它们可能是C对象的代理,实际上可能是相同的。这不是直观的,它是这样的,但很明显,这是怎么回事。发生这种情况似乎很奇怪,因为存在管理器对象,用于管理事件实例——人们会认为这些事件是“真实的”共享事件。而且,将事件开箱即用也很有意义,因为如果不是这样,它们就没有用处了。@vlad ardelean当然你是对的。在发布之前,我没有考虑太多。@Michal不用担心,谢谢你的帮助:)这个问题不那么琐碎,所以错过一些东西是可以理解的。
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'
def print_globals():
    print globals()