python-多重处理:为什么在复制列表时与子进程共享一个numpy数组?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python-多重处理:为什么在复制列表时与子进程共享一个numpy数组?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2607字,纯文字阅读大概需要4分钟。
内容图文
![python-多重处理:为什么在复制列表时与子进程共享一个numpy数组?](/upload/InfoBanner/zyjiaocheng/947/9a23ec557a954f1e872243defbdccbf4.jpg)
我使用此script(请参阅最后的代码)来评估在父进程派生时是共享还是复制了全局对象.
简要地说,脚本创建了一个全局数据对象,并且子进程对数据进行迭代.该脚本还监视内存使用情况,以评估对象是否在子进程中被复制.
结果如下:
>数据= np.ones((N,N)).在子进程中的操作:
data.sum().结果:数据共享(无副本)
> data = list(range(pow(10,8))).子进程中的操作:sum(data).结果:数据被复制.
> data = list(range(pow(10,8))).子进程中的操作:对于数据中的x:通过.结果:数据被复制.
由于写时复制,因此预期结果1).我对结果2)和3)感到有些困惑.为什么要复制数据?
脚本
import multiprocessing as mp
import numpy as np
import logging
import os
logger = mp.log_to_stderr(logging.WARNING)
def free_memory():
total = 0
with open('/proc/meminfo', 'r') as f:
for line in f:
line = line.strip()
if any(line.startswith(field) for field in ('MemFree', 'Buffers', 'Cached')):
field, amount, unit = line.split()
amount = int(amount)
if unit != 'kB':
raise ValueError(
'Unknown unit {u!r} in /proc/meminfo'.format(u = unit))
total += amount
return total
def worker(i):
x = data.sum() # Exercise access to data
logger.warn('Free memory: {m}'.format(m = free_memory()))
def main():
procs = [mp.Process(target = worker, args = (i, )) for i in range(4)]
for proc in procs:
proc.start()
for proc in procs:
proc.join()
logger.warn('Initial free: {m}'.format(m = free_memory()))
N = 15000
data = np.ones((N,N))
logger.warn('After allocating data: {m}'.format(m = free_memory()))
if __name__ == '__main__':
main()
详细结果
运行1个输出
[WARNING / MainProcess]初始免费:25.1 GB
[WARNING / MainProcess]分配数据后:23.3 GB
[WARNING / Process-2]可用内存:23.3 GB
[WARNING / Process-4]可用内存:23.3 GB
[WARNING / Process-1]可用内存:23.3 GB
[WARNING / Process-3]可用内存:23.3 GB
运行2输出
[WARNING / MainProcess]初始免费:25.1 GB
[WARNING / MainProcess]分配数据后:21.9 GB
[WARNING / Process-2]可用内存:12.6 GB
[WARNING / Process-4]可用内存:12.7 GB
[WARNING / Process-1]可用内存:16.3 GB
[WARNING / Process-3]可用内存:17.1 GB
运行3输出
[WARNING / MainProcess]初始免费:25.1 GB
[WARNING / MainProcess]分配数据后:21.9 GB
[WARNING / Process-2]可用内存:12.6 GB
[WARNING / Process-4]可用内存:13.1 GB
[WARNING / Process-1]可用内存:14.6 GB
[WARNING / Process-3]可用内存:19.3 GB
解决方法:
它们都是写时复制.您所缺少的是,当您这样做时,例如
for x in data:
pass
由于x依次绑定到每个对象,因此数据中包含的每个对象的引用计数都会暂时增加1.对于int对象,CPython中的refcount是基本对象布局的一部分,因此将复制该对象(您确实对其进行了更改,因为refcount发生了变化).
要使之更类似于numpy.ones的情况,请尝试例如
data = [1] * 10**8
然后,只有一个唯一的对象被列表引用了很多(10 ** 8)次,因此几乎没有要复制的内容(同一对象的refcount会增加和减少很多次).
内容总结
以上是互联网集市为您收集整理的python-多重处理:为什么在复制列表时与子进程共享一个numpy数组?全部内容,希望文章能够帮你解决python-多重处理:为什么在复制列表时与子进程共享一个numpy数组?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。