modlwip: 内存出时发送的非屏蔽套接字块
港口、板和/或硬件
并非针对特定港口——该代码是extmod/modlwip.c'中的通用lwip'路径,由每个`MICROPY-PY-LWIP ' 港口(rp2、stm32、mimxrt、esp8266,.)共用。 以开通MVRT1062(一.MX RT1062,cyw43 WiFi)测量.
缩微Python 版本
主':extmod/modlwip.c'、lwip tcp send'、ERR-MEM' ' for (;) ' 环(约L1091-1110),在10 s 上限下用`poll sockets()'等。 在v1.28.0线上也存在同样的回路,它在那里用"mp hal delay ms(50)"等;下面的数字是在以v1.28.0为基础的OpenMV分叉上测得.
- 复制
- 在 " MEM SIZE " / " MEMP NUM TCP SEG " 游泳池小到可以排出未收起的队列而 " tcp sndbuf " 仍然报告房间的港口上,向接收窗口回放的同伴写 " socket " ( " setblocking(false) " )。
select.select ( [], [sock], [ ]' 返回可写入的套接字(POLLOUT为tcp sndbuf')。sock.write(buf)'然后在lwip tcp send'内进行屏蔽,而不是返回`AGAIN'。
触发器是tcp write'返回ERR MEM',而`tcp sndbuf'是非0——字节计数器和段/堆积池是不同的资源,在记忆压力下有不同意见。
- 预期行为
" sock.write () " 在非屏蔽的套接字上返回 " EAAIN " ,因为它已经从
'tcp sndbuf=0' 路径在同一函数中. 呼叫者重复; 没有丢失数据, 因为
tcp write' 在ERR MEM'上排入零字节。
观察行为
`sock.write ()' 以至10 s 封顶。 ‘ERR MEM'环无‘socket->时间出局=0' 检查,所以一个非阻塞插座在那里等待。 循环文件本身:
/ 注意: 如果套接字是非屏蔽的, 那么这个代码实际上会屏蔽到 // 有足够的内存做写作, 但在这个阶段,我们已经 //承诺能够写出数据.
lwip tcp send'尚未归还给呼叫者,承诺以tcp sndbuf'为基础,而失败则取自分块/堆积池。 在单行道事件回路上,块会拖住所有其他任务. 在OpenMV RT1062上测量,为一个读取器提供MJPEG的流线:
最差的单个 " 写() " 达到1553086个,超过320个跑道的54个事件超过100米。
补充信息
ERR MEM ' 循环中的一个警卫返回Eaaain ' 时socket->timext ==0'——在tcp output ()'之后,在等待之前——把最差的`write ()'切到3484个我们,在同一测试中将100多米的事件切到0个,对阻塞套座没有改动。 乐于对 " 主人 " 开放公关,如果这一方向是可以接受的。
行为守则
对,我同意.
内容来源: micropython/micropython