1

我正在使用 python 的多处理模块并且对此有一些困惑。

基本上,我最初将一些数据存储在主进程中,如顶部命令所示,大约为 16GB(主内存大小)。我已将这些数据存储为全局变量。

然后对这些数据进行多重处理,并相应地进行不同的处理。

现在我看到多处理正在发生,即所有进程都有自己的 CPU 利用率,但是所有进程的内存每个 16 GB.. 为什么会这样.?? 难道它不应该使用我通过全局变量的引用传递的相同内存..请一些想法。

top 命令的输出如下:-

PID 用户 PR NI VIRT RES SHR S %CPU %MEM TIME+ 命令 13908 管理员 20 0 16.7g 16g 848 R 100.0 17.3 0:32.92 python
13429 管理员 20 0 16.7g 16g 3336 S 0.0 17.3 15:06.97 python
16.7g 管理员16G 848 R 100.3 17.3 0:32.94 Python
13911 Admin 20 0 16.7G 16G 16G 840 R 100.0 17.3 0:33.02 Python
13912 Admin 20 0 16.7G 16.7G 16G 16G 16G 836 R 99.6 R 99.6 R 99.6 17.6 17.6 17.6 17.6 17.6 17.6 17.3 0:33.00 Python
13907 Adman 20 0 16.7G 16.7 G 16.7 G 796 6.66 6.66 r re 0:33.06 蟒蛇
13909 管理员 20 0 16.7g 16g 796 R 99.6 17.3 0:32.93 蟒蛇

4

2 回答 2

3

模块产生的每个进程multiprocessing都在一个单独的地址空间中。在创建新进程后,原始进程拥有的所有物理和虚拟内存至少在逻辑上独立于新进程,但最初每个新进程都是旧进程的完全副本(好吧,请参见脚注)。因此,每个都将具有与原始大小相同的虚拟大小 (16.7 GB)。

使用“写时复制”尽可能多地共享实际的底层物理页面。随着各种副本的运行并对它们的虚拟内存进行更改,内核将根据需要复制底层物理页面。永远不会被写入的内存可以在所有副本之间共享。因此,即使每个进程似乎都在消耗大量 RAM,但实际上并非如此。但是,如果您写入其中的大部分——即,如果每个单独的进程更改了 16 GB 数据的大部分——那么它们都将拥有单独的副本,并使用更多的物理 RAM。

如果您希望它们共享修改,该multiprocessing模块确实提供了一些共享数据的方法(请参阅http://docs.python.org/library/multiprocessing.html中的“共享内存”部分)(但请考虑锁定的工作原理; 见文档)。


脚注:在 fork 或 clone 系统调用之后,原始版本和克隆版本之间有一个微小的区别:原始版本取回克隆的 ID,而克隆取回数字零。

于 2012-04-29T02:53:36.633 回答
2

将多处理模块视为 os.fork() 周围的语法糖。

现在什么是叉子?当一个进程分叉时,操作系统会创建一个具有新进程 ID 的新子进程,复制父进程的状态(内存、环境变量等)。

于 2012-04-29T02:53:34.087 回答