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保存MongoDB上的文件到本地的方法
Mar 16 Python
浅谈Python中的私有变量
Feb 28 Python
python判断计算机是否有网络连接的实例
Dec 15 Python
Python学习笔记之pandas索引列、过滤、分组、求和功能示例
Jun 03 Python
python logging模块的使用总结
Jul 09 Python
Python解析命令行读取参数之argparse模块
Jul 26 Python
python超时重新请求解决方案
Oct 21 Python
利用PyCharm操作Github(仓库新建、更新,代码回滚)
Dec 18 Python
解析pip安装第三方库但PyCharm中却无法识别的问题及PyCharm安装第三方库的方法教程
Mar 10 Python
在python里创建一个任务(Task)实例
Apr 25 Python
keras绘制acc和loss曲线图实例
Jun 15 Python
Python OpenCV之常用滤波器使用详解
Apr 07 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读书笔记_运算符详解
2016/07/01 PHP
php实现与python进行socket通信的方法示例
2017/08/30 PHP
laravel-admin的图片删除实例
2019/09/30 PHP
刷新时清空文本框内容的js代码
2007/04/23 Javascript
js控制表单不能输入空格的小例子
2013/11/20 Javascript
php和js对数据库图片进行等比缩放示例
2014/04/28 Javascript
Bootstrap每天必学之基础排版
2015/11/20 Javascript
详解js数组的完全随机排列算法
2016/12/16 Javascript
jQueryUI 拖放排序遇到滚动条时有可能无法执行排序的小bug及解决方案
2016/12/19 Javascript
angularjs+bootstrap菜单的使用示例代码
2017/03/07 Javascript
jQuery+pjax简单示例汇总
2017/04/21 jQuery
Vue.js实现图片的随意拖动方法
2018/03/08 Javascript
vue-cli脚手架config目录下index.js配置文件的方法
2018/03/13 Javascript
layui layer select 选择被遮挡的解决方法
2019/09/21 Javascript
小程序实现图片预览裁剪插件
2019/11/22 Javascript
JS实现横向轮播图(中级版)
2020/01/18 Javascript
Vue实现简易购物车页面
2020/12/30 Vue.js
[01:01:35]Optic vs paiN 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
把MySQL表结构映射为Python中的对象的教程
2015/04/07 Python
深入理解Python 关于supper 的 用法和原理
2018/02/28 Python
python线程中同步锁详解
2018/04/27 Python
PyCharm+PySpark远程调试的环境配置的方法
2018/11/29 Python
浅析python参数的知识点
2018/12/10 Python
Django stark组件使用及原理详解
2019/08/22 Python
python list数据等间隔抽取并新建list存储的例子
2019/11/27 Python
CSS3动画:5种预载动画效果实例
2017/04/05 HTML / CSS
关于Java String的一道面试题
2013/09/29 面试题
教育学习自我评价
2014/02/03 职场文书
岗位竞聘演讲稿范文
2014/04/24 职场文书
创先争优活动党员公开承诺书
2014/08/29 职场文书
毕业生实习期转正自我鉴定
2014/09/26 职场文书
2015年秘书个人工作总结
2015/04/25 职场文书
预备党员表决心的话
2015/09/22 职场文书
演讲稿之开卷有益
2019/08/07 职场文书
2022微信温控新功能上线
2022/05/09 数码科技
服务器间如何实现文件共享
2022/05/20 Servers