Python如何发送与接收大型数组


Posted in Python onAugust 07, 2020

问题

你要通过网络连接发送和接受连续数据的大型数组,并尽量减少数据的复制操作。

解决方案

下面的函数利用 memoryviews 来发送和接受大数组:

# zerocopy.py

def send_from(arr, dest):
  view = memoryview(arr).cast('B')
  while len(view):
    nsent = dest.send(view)
    view = view[nsent:]

def recv_into(arr, source):
  view = memoryview(arr).cast('B')
  while len(view):
    nrecv = source.recv_into(view)
    view = view[nrecv:]

为了测试程序,首先创建一个通过socket连接的服务器和客户端程序:

>>> from socket import *
>>> s = socket(AF_INET, SOCK_STREAM)
>>> s.bind(('', 25000))
>>> s.listen(1)
>>> c,a = s.accept()
>>>

在客户端(另外一个解释器中):

>>> from socket import *
>>> c = socket(AF_INET, SOCK_STREAM)
>>> c.connect(('localhost', 25000))
>>>

本节的目标是你能通过连接传输一个超大数组。这种情况的话,可以通过 array 模块或 numpy 模块来创建数组:

# Server
>>> import numpy
>>> a = numpy.arange(0.0, 50000000.0)
>>> send_from(a, c)
>>>

# Client
>>> import numpy
>>> a = numpy.zeros(shape=50000000, dtype=float)
>>> a[0:10]
array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
>>> recv_into(a, c)
>>> a[0:10]
array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
>>>

讨论

在数据密集型分布式计算和平行计算程序中,自己写程序来实现发送/接受大量数据并不常见。 不过,要是你确实想这样做,你可能需要将你的数据转换成原始字节,以便给低层的网络函数使用。 你可能还需要将数据切割成多个块,因为大部分和网络相关的函数并不能一次性发送或接受超大数据块。

一种方法是使用某种机制序列化数据——可能将其转换成一个字节字符串。 不过,这样最终会创建数据的一个复制。 就算你只是零碎的做这些,你的代码最终还是会有大量的小型复制操作。

本节通过使用内存视图展示了一些魔法操作。 本质上,一个内存视图就是一个已存在数组的覆盖层。不仅仅是那样, 内存视图还能以不同的方式转换成不同类型来表现数据。 这个就是下面这个语句的目的:

view = memoryview(arr).cast('B')

它接受一个数组 arr并将其转换为一个无符号字节的内存视图。这个视图能被传递给socket相关函数, 比如 socket.send() send.recv_into() 。 在内部,这些方法能够直接操作这个内存区域。例如,sock.send() 直接从内存中发生数据而不需要复制。 send.recv_into() 使用这个内存区域作为接受操作的输入缓冲区。

剩下的一个难点就是socket函数可能只操作部分数据。 通常来讲,我们得使用很多不同的 send() recv_into() 来传输整个数组。 不用担心,每次操作后,视图会通过发送或接受字节数量被切割成新的视图。 新的视图同样也是内存覆盖层。因此,还是没有任何的复制操作。

这里有个问题就是接受者必须事先知道有多少数据要被发送, 以便它能预分配一个数组或者确保它能将接受的数据放入一个已经存在的数组中。 如果没办法知道的话,发送者就得先将数据大小发送过来,然后再发送实际的数组数据。

以上就是Python如何发送与接收大型数组的详细内容,更多关于Python发送接收大型数组的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
wxpython 学习笔记 第一天
Mar 16 Python
python类继承用法实例分析
May 27 Python
Python 实现在文件中的每一行添加一个逗号
Apr 29 Python
使用matplotlib画散点图的方法
May 25 Python
python实现一个简单的ping工具方法
Jan 31 Python
python做反被爬保护的方法
Jul 01 Python
python可视化篇之流式数据监控的实现
Aug 07 Python
python 图片二值化处理(处理后为纯黑白的图片)
Nov 01 Python
python实现宿舍管理系统
Nov 22 Python
PyQt5如何将.ui文件转换为.py文件的实例代码
May 26 Python
通过Python pyecharts输出保存图片代码实例
Nov 25 Python
Python词云的正确实现方法实例
May 08 Python
Python如何实现远程方法调用
Aug 07 #Python
记一次django内存异常排查及解决方法
Aug 07 #Python
python正则表达式 匹配反斜杠的操作方法
Aug 07 #Python
Pygame框架实现飞机大战
Aug 07 #Python
python爬取网易云音乐热歌榜实例代码
Aug 07 #Python
Python变量格式化输出实现原理解析
Aug 06 #Python
Python实现Canny及Hough算法代码实例解析
Aug 06 #Python
You might like
玛琪朵 Macchiato
2021/03/03 咖啡文化
PHP输出控制功能在简繁体转换中的应用
2006/10/09 PHP
linux下删除7天前日志的代码(php+shell)
2011/01/02 PHP
php eval函数一句话木马代码
2015/05/21 PHP
php比较相似字符串的方法
2015/06/05 PHP
PHP超低内存遍历目录文件和读取超大文件的方法
2019/05/01 PHP
PHP进阶学习之反射基本概念与用法分析
2019/06/18 PHP
PHP defined()函数的使用图文详解
2019/07/20 PHP
PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作详解
2020/02/12 PHP
javascript 动态添加表格行
2006/06/22 Javascript
jQuery验证Checkbox是否选中的代码 推荐
2011/09/04 Javascript
jQuery EasyUI API 中文文档 - Dialog对话框
2011/11/15 Javascript
jQuery学习笔记之jQuery+CSS3的浏览器兼容性
2015/01/19 Javascript
jQuery ajax全局函数处理session过期后的ajax跳转问题
2016/06/03 Javascript
bootstrap datetimepicker日期插件超详细使用方法介绍
2017/02/23 Javascript
Vue 2.0中生命周期与钩子函数的一些理解
2017/05/09 Javascript
gulp解决跨域的配置文件问题
2017/06/08 Javascript
get  post jsonp三种数据交互形式实例详解
2017/08/25 Javascript
从setTimeout看js函数执行过程
2017/12/19 Javascript
解决vue侦听器watch,调用this时出现undefined的问题
2020/10/30 Javascript
微信小程序实现分页加载效果
2020/11/19 Javascript
python分析网页上所有超链接的方法
2015/05/08 Python
python使用udp实现聊天器功能
2018/12/10 Python
在python中对变量判断是否为None的三种方法总结
2019/01/23 Python
Python enumerate函数功能与用法示例
2019/03/01 Python
Django 在iframe里跳转顶层url的例子
2019/08/21 Python
墨西哥网上超市:Superama
2018/07/10 全球购物
澳大利亚运动鞋零售商:The Athlete’s Foot
2018/11/04 全球购物
PHP中如何创建和修改数组
2012/05/02 面试题
设计毕业生简历中的自我评价
2013/10/01 职场文书
妇产科护士自我鉴定
2013/10/15 职场文书
法院信息化建设方案
2014/05/21 职场文书
开发房地产协议书
2014/09/14 职场文书
解决使用了nginx获取IP地址都是127.0.0.1 的问题
2021/09/25 Servers
24年收藏2000多部退役军用电台
2022/02/18 无线电
CSS实现背景图片全屏铺满自适应的3种方式
2022/07/07 HTML / CSS