Python 3.8中SharedMemory大小定义及使用异常相关问题咨询
下面按提问顺序逐一解答:
1. 指定size=1字节,写入长度为4的bytearray无异常抛出的原因
你实际得到的共享内存大小为4096字节,写入的内容长度远小于实际分配的内存总大小,没有触发内存越界,因此不会抛出异常。memoryview类型只会在访问范围超出它绑定的内存块总长度时才会抛出越界错误,你写入的范围在合法区间内,自然运行正常。
2. 直接打印buffer时输出内存地址的原因
shm.buf返回的是memoryview类型的对象,Python对memoryview默认的字符串表示规则就是输出<memory at 内存地址>格式,不会直接打印内存中存储的二进制内容。如果需要查看内容,可以先转为bytes类型:print(bytes(buffer))。
3. 指定size为1字节,实际分配大小为4096字节的原因
共享内存由操作系统内核负责分配,内核分配内存的最小单位是内存页,绝大多数桌面/服务器操作系统的默认页大小就是4096字节(4KB)。就算你只申请1字节的共享内存,内核也会分配一整页的内存空间,因此最终shm.size显示为4096,这是操作系统层面的限制,和Python标准库实现无关。
4. 原buffer地址和buffer[3:4]的地址相差3×16×16字节的原因
你打印出的地址不是共享内存本身的虚拟内存地址,是memoryview这个Python对象在解释器堆内存中的存储地址。不同的memoryview实例是独立的Python对象,它们的存储地址由Python解释器的内存分配逻辑决定,和共享内存块内部的偏移量没有任何对应关系,这个差值没有实际业务意义。
5. buffer[3:4]和buffer[1:3]的切片打印出的内存地址相同的原因
这是Python的临时小对象复用机制导致的:第一个切片buffer[3:4]是临时对象,打印完成后没有其他引用,会被解释器立刻回收,它占用的内存空间会被释放。后续创建buffer[1:3]切片时,解释器会直接复用刚释放的这块内存来存储新的memoryview对象,因此打印出来的地址完全相同,这个地址是Python对象的存储地址,和它们指向的共享内存内容没有关系。
内容的提问来源于stack exchange,提问作者Cherrymelon
相关产品推荐
相关产品推荐

