微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用bufsize而不是2的幂调用socket.recv的实际影响是什么?

如何解决用bufsize而不是2的幂调用socket.recv的实际影响是什么?

我非常确定“ 2的幂”建议是基于编辑中的错误,因此不应视为必需 条件

响应Python问题#756104,该特定建议已添加到Python 2.5文档中(并反向移植到Python2.4.3docs)。报告程序使用的缓冲区大小过大,这促使更新。socket.recv()

提姆·彼得斯(Tim Peters)引入了“ 2的幂”概念:

我希望您是历史上唯一尝试将这么大的值传递给recv()的人-即使它起作用了,您几乎肯定会用尽内存来分配1.9GB的缓冲区空间。套接字是一种低级别的工具,

(强调粗体)。我曾与Tim一起工作过,他在网络编程和硬件方面拥有丰富的经验,因此总的来说,我在做出这样的评论时会说服他。他特别喜欢Windows 95堆栈,他称它为煤矿中的金丝雀,因为它能够在压力下失效。但请注意,他说 ,而不是 要求 使用2的幂。

正是该措辞导致了文档更新:

这是一个文档错误;应该向用户“警告”一些事情。

这一次引起了我的注意,两个不同的人在#python中问了这个,所以也许我们应该在recv()文档中输入类似以下内容

“”“ 对于具有硬件和网络现实最佳匹配,所述 的值‘缓冲’应该是2的功率相对较小的, 例如,4096。 ‘’”

如果您认为措辞正确,只需将错误分配给我,我会解决

没有人质疑在这里断言“2的权力”,而是从移动编辑器 是很常见 在几个回复的空间。

对我来说,这些提议文档更新更关心的是确保你使用一个 小的缓冲区 ,而不是它是否是2的幂,这并不是说这是不好 的建议 。然而,与内核交互的任何低级缓冲区都可以与内核数据结构保持一致。

但是,尽管可能存在一个深奥的堆栈,其中缓冲区的大小是2的幂甚至更重要,但我怀疑蒂姆·彼得斯(Tim Peters)的经验(这是 普遍的做法 )是否打算以这种铁定的方式进行铸造。如果不同的缓冲区大小对于您的特定用例更有意义,则只需忽略它。

解决方法

要从python中的套接字读取数据,请调用socket.recv,它具有以下签名:

socket.recv(bufsize[,flags])

socket.recvpython文档含糊地指出:

注意: 为了与硬件和网络实际情况保持最佳匹配,bufsize的值应为2的较小乘方,例如4096。

问题 :“ 与硬件和网络现实最匹配 ”是什么意思?将bufsize设置为非2的幂次方有什么 实际 影响?

我已经看到许多其他
建议,以使其读数为2的幂。我也很清楚为什么将数组长度设为2的幂通常很有用的原因(长度的位移位/掩码操作,最佳FFT数组大小,等等),但它们取决于应用程序。我只是没有看到使用它的一般原因socket.recv。当然不是python文档中特定建议的重点。我也没有在基础python代码中看到任何二次幂优化来使其成为特定于python的建议

例如…如果您有一个协议,其中确切知道传入的数据包长度,则最好仅“最多”读取要处理的数据包所需的内容,否则可能会吞噬下一个数据包那会很烦人。如果我当前正在处理的数据包只有42个字节待处理,那么我只会将bufsize设置为42。

我想念什么?当我必须选择一个任意的缓冲区/数组大小时,通常(总是?)将长度乘以2的幂,以防万一。这只是多年以来养成的习惯。python文档也是习惯的受害者吗?

这不是python独有的,但是由于我专门引用python文档,因此将其标记为python。


更新 :我只是在系统的内核级别上检查了缓冲区的大小(或者至少我认为我做了…我做了cat /proc/sys/net/core/rmem_default),它是124928。不是2的幂。 rmem_max是131071,显然也不是2的幂。

在深入研究这一点时,我真的看不到两项建议的作用。我准备将其称为虚假推荐…

我还添加了tcpC标签,因为它们也很重要。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。