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 相关文章推荐
浅谈python 线程池threadpool之实现
Nov 17 Python
[原创]教女朋友学Python3(二)简单的输入输出及内置函数查看
Nov 30 Python
python处理大日志文件
Jul 23 Python
对django后台admin下拉框进行过滤的实例
Jul 26 Python
Python Web框架之Django框架Form组件用法详解
Aug 16 Python
python爬虫之爬取百度音乐的实现方法
Aug 24 Python
Python插入Elasticsearch操作方法解析
Jan 19 Python
解决更改AUTH_USER_MODEL后出现的问题
May 14 Python
Python matplotlib可视化实例解析
Jun 01 Python
k-means 聚类算法与Python实现代码
Jun 01 Python
Keras中 ImageDataGenerator函数的参数用法
Jul 03 Python
python 基于selenium实现鼠标拖拽功能
Dec 24 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
php实现首页链接查询 友情链接检查的代码
2010/01/05 PHP
无JS,完全php面向过程数据分页实现代码
2012/08/27 PHP
PHP基础陷阱题(变量赋值)
2012/09/12 PHP
详解PHP执行定时任务的实现思路
2015/12/21 PHP
thinkphp3.x连接mysql数据库的方法(具体操作步骤)
2016/05/19 PHP
基于jquery的跨域调用文件
2010/11/19 Javascript
根据身份证号自动输出相关信息(籍贯,出身日期,性别)
2013/11/15 Javascript
可恶的ie8提示缺少id未定义
2014/03/20 Javascript
javascript中parseInt()函数的定义和用法分析
2014/12/20 Javascript
jquery实现动态操作select选中
2015/02/11 Javascript
详解Angular路由 ng-route和ui-router的区别
2017/05/22 Javascript
Angularjs的$http异步删除数据详解及实例
2017/07/27 Javascript
JS实现简单表格排序操作示例
2017/10/07 Javascript
如何选择适合你的JavaScript框架
2017/11/20 Javascript
浅谈jquery fullpage 插件增加头部和版权的方法
2018/03/20 jQuery
AngularJS日期格式化常见操作实例分析
2018/05/17 Javascript
微信小程序scroll-view实现滚动穿透和阻止滚动的方法
2018/08/20 Javascript
JavaScript实现简易聊天对话框(加滚动条)
2020/02/10 Javascript
Node登录权限验证token验证实现的方法示例
2020/05/25 Javascript
详解Python中的__new__()方法的使用
2015/04/09 Python
点球小游戏python脚本
2018/05/22 Python
Python使用dict.fromkeys()快速生成一个字典示例
2019/04/24 Python
使用python socket分发大文件的实现方法
2019/07/08 Python
Jupyter notebook如何修改平台字体
2020/05/13 Python
PyTorch中Tensor的数据类型和运算的使用
2020/09/03 Python
芬兰汽车配件商店:Autonvaraosat24
2017/01/30 全球购物
Myprotein亚太地区:欧洲第一在线运动营养品牌
2020/12/20 全球购物
毕业生求职推荐信
2013/11/04 职场文书
护理学毕业生求职信
2013/11/14 职场文书
代领毕业证委托书
2014/08/02 职场文书
小学总务工作总结
2015/08/13 职场文书
银行岗位培训心得体会
2016/01/09 职场文书
python 破解加密zip文件的密码
2021/04/22 Python
php png失真的原因及解决办法
2021/10/24 PHP
CSS SandBox应用场景及常见问题
2022/06/25 HTML / CSS
ORACLE中dbms_output.put_line输出问题的解决过程
2022/06/28 Oracle