Python如何发送与接收大型数组
作者:David Beazley 发布时间:2022-07-26 06:54:54
问题
你要通过网络连接发送和接受连续数据的大型数组,并尽量减少数据的复制操作。
解决方案
下面的函数利用 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()
来传输整个数组。 不用担心,每次操作后,视图会通过发送或接受字节数量被切割成新的视图。 新的视图同样也是内存覆盖层。因此,还是没有任何的复制操作。
这里有个问题就是接受者必须事先知道有多少数据要被发送, 以便它能预分配一个数组或者确保它能将接受的数据放入一个已经存在的数组中。 如果没办法知道的话,发送者就得先将数据大小发送过来,然后再发送实际的数组数据。
来源:https://python3-cookbook.readthedocs.io/zh_CN/latest/c11/p13_sending_receiving_large_arrays.html


猜你喜欢
- MySQL超长字符截断又名"SQL-Column-Truncation",是安全研究者Stefan Esser在2008
- 根据导师作业安排,在学习数字图像处理(刚萨雷斯版)第六章 彩色图像处理 中的彩色模型后,导师安排了一个比较有趣的作业:融合原理为:1 注意:
- 1、说明(1)写函数时,可以为每个参数指定默认值。当调用函数为参数提供实际参数时,Python将使用指定的实际参数;否则,将使用参数的默认值
- isnull()Null 值指出变量不包含有效数据。Null 与 Empty 不同,后者指出变量未经初始化。Null 与零长度字符串 (&q
- 本文实例讲述了Python使用正则表达式过滤或替换HTML标签的方法。分享给大家供大家参考,具体如下:python正则表达式关键内容:pyt
- 关于最近要在python下做可视化界面的设计,想到之前用QtDesigner来画界面很是方便,当时画完之后都要手动在终端输入 pyuic5
- 流式布局流式布局,也叫做瀑布流布局,是网页中经常使用的一种页面布局方式,它的原理就是将高度固定,然后图片的宽度自适应,这样加载出来的图片看起
- 一,索引的重要性索引用于快速找出在某个列中有一特定值的行。不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行。表越大,
- 1. 设置fomat格式,如下: # 取前5个字符,跳过4个字符华,再取3个字符 format = '5s 4x 3s' 2
- 养成良好的编码习惯,一个合格的程序员需要掌握一些编写单元测试的能力。单元测试也可以整体上提升我们的代码质量,这里介绍下 VUE 组件的单元测
- MAC 中mysql密码忘记解决办法最近项目用到MySQL,之前装过一个,可是忘记了当时设置的密码,然后走上了修改密码的坎坷道路。在百度,G
- 本文实例讲述了PHP设计模式之装饰器模式定义与用法。分享给大家供大家参考,具体如下:什么是装饰器模式作为一种结构型模式, 装饰器(Decor
- 1. 调度器scheduler的作用我们都知道,在Go语言中,程序运行的最小单元是gorouines。然而程序的运行最终都是要交给操作系统来
- 什么是mtcnn和facenet1、mtcnnMTCNN,英文全称是Multi-task convolutional neural netw
- 微信小程序报错VM1305:1 thirdScriptErrorCannot read property 'name' of
- 问题描述输入样例:Only the 11 CAPItal LeTtERS are replaced输出样例:Only the 11 XZKI
- 第一步my-default.ini 添加配置:#绑定IPv4和3306端bind-address = 127.0.0.1port = 330
- 本文是对《Python Qt GUI快速编程》的第10章的例子剪贴板用Python3+PyQt5进行改写,分别对文本,图片和html文本的复
- 前段时间写了个比较简单的批量水印添加的python实现方式,将某个文件夹下面的图片全部添加上水印。今天正好有时间就做了一个UI应用的封装,这
- JDBC连接mysql处理中文时乱码解决办法详解近日,整合的项目需要跟一个比较老版本的mysql服务器连接,使用navicat查看,发现此m