os.fork()会在写入时使用copy还是在Python中执行父进程的完整副本?

时间:2013-02-18 17:15:29

标签: python linux fork

我想将一个相当大的数据结构加载到一个进程中然后分叉,希望减少总内存消耗。 os.fork将以这种方式工作还是复制Linux(RHEL)中的所有父进程?

2 个答案:

答案 0 :(得分:15)

即使使用了COW,CPython也会使用引用计数并将引用计数存储在每个对象的标题中。因此,除非您不对该数据执行任何操作,否则您将很快对所讨论的内存进行虚假写入,这将迫使系统复制数据。把它传递给一个函数?这是另一个引用,INCREF,写入COW的内存。将其存储在变量或对象属性中?相同。即使只是查找一个方法呢?同上。 由于各种原因,一些内置数据结构将其大部分数据与对象分开(例如,大多数集合)。如果这些最终出现在不同的页面上 - 或者COW所使用的任何粒度 - 你可能会幸运地获得这些。但是,从这样的集合引用的对象不是免除的 - 使用它操作它的引用计数是相同的。

此外,将共享一些数据,因为设计中没有对它进行写入(例如,本机CPython代码),以及fork'进程未触及的某些对象可能共享(我老实说不确定;我认为循环GC不会写入对象)。但Python代码使用的Python对象几乎可以保证写入。类似的推理适用于PyPy,Jython,IronPython等(只是他们在对象标题中使用位而不是进行引用计数)但我无法保证所有可能的配置。

答案 1 :(得分:3)

如果您使用的是* nix系统,那么os.fork()将使用系统的fork()调用,至少在Linux的情况下,该调用是写时复制:

http://linux.die.net/man/2/fork

参见“注释”部分