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图像处理之镜像实现方法
May 30 Python
python简单实现计算过期时间的方法
Jun 09 Python
获取Django项目的全部url方法详解
Oct 26 Python
Python学生成绩管理系统简洁版
Apr 05 Python
python机器学习理论与实战(二)决策树
Jan 19 Python
python清除函数占用的内存方法
Jun 25 Python
python文字转语音的实例代码分析
Nov 12 Python
python 解决print数组/矩阵无法完整输出的问题
Feb 19 Python
浅谈python量化 双均线策略(金叉死叉)
Jun 03 Python
在Pytorch中使用Mask R-CNN进行实例分割操作
Jun 24 Python
使用Keras建立模型并训练等一系列操作方式
Jul 02 Python
如何用python写个模板引擎
Jan 14 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
在Windows版的PHP中使用ADO
2006/10/09 PHP
php学习之 数组声明
2011/06/09 PHP
PHP的魔术常量__METHOD__简介
2014/07/08 PHP
抛弃 PHP 代价太高
2016/04/26 PHP
Laravel 将数据表的数据导出,并生成seeds种子文件的方法
2019/10/09 PHP
discuz论坛更换域名,详细文件修改步骤
2020/12/09 PHP
云网广告中的代码,提示出错,大家找找
2006/11/21 Javascript
javascript算法学习(直接插入排序)
2011/04/12 Javascript
复制js对象方法(详解)
2013/07/08 Javascript
Javascript 构造函数详解
2014/10/22 Javascript
Json解析的方法小结
2016/06/22 Javascript
浅析JavaScript中var that=this
2017/02/17 Javascript
jquery DataTable实现前后台动态分页
2017/06/17 jQuery
Kindeditor单独调用多图上传实例
2017/07/31 Javascript
浅谈es6语法 (Proxy和Reflect的对比)
2017/10/24 Javascript
关于axios如何全局注册浅析
2018/01/14 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
使用Javascript简单计算器
2018/11/17 Javascript
记一次Vue.js混入mixin的使用(分权限管理页面)
2019/04/17 Javascript
javascript实现蒙版与禁止页面滚动
2020/01/11 Javascript
Python之str操作方法(详解)
2017/06/19 Python
pandas多级分组实现排序的方法
2018/04/20 Python
对Python中list的倒序索引和切片实例讲解
2018/11/15 Python
Python3 安装PyQt5及exe打包图文教程
2019/01/08 Python
浅谈python str.format与制表符\t关于中文对齐的细节问题
2019/01/14 Python
基于HTML5 Canvas 实现商场监控实例详解
2017/11/20 HTML / CSS
html5拖曳操作 HTML5实现网页元素的拖放操作
2013/01/02 HTML / CSS
后勤部长岗位职责
2013/12/14 职场文书
销售行政专员职责
2014/01/03 职场文书
乐观自信演讲稿范文
2014/05/21 职场文书
班级口号大全
2014/06/09 职场文书
中国梦演讲稿5分钟
2014/08/19 职场文书
2015年小学生新年寄语
2014/12/08 职场文书
2016三八妇女节校园广播稿
2015/12/17 职场文书
新员工入职感言范文!
2019/07/04 职场文书
Python机器学习应用之工业蒸汽数据分析篇详解
2022/01/18 Python