【发布时间】:2017-07-19 23:06:45
【问题描述】:
有很多例子展示了如何将单个变量甚至结构的单个成员写入共享内存,但是有没有办法将整个结构放入共享内存,以便您可以简单地操作结构来更新共享内存?
这是我目前正在做的一个例子(在我的实际程序中 - 结构中有超过 50 个字段 - 到我完成时可能超过 100 个)。它每 0.05 秒用 x,y,z 坐标更新共享内存。虽然它按原样工作,但它在每一步都打包一个新结构并将整个内容写入共享内存 - 这对我来说似乎效率低下。
import mmap
import struct
import ctypes
import time
import random
class GenericData(ctypes.Structure):
_pack_ = 4
_fields_ = [
('PosX', ctypes.c_float),
('PosY', ctypes.c_float),
('PosZ', ctypes.c_float),
]
# fake getters:
def getX():
return random.random()*10
getZ = getY = getX
def main():
buff = mmap.mmap(0, ctypes.sizeof(GenericData), "$MyTag$")
data = GenericData()
fmt = ''.join([f[1]._type_ for f in data._fields_])
while (1):
data.PosX = getX()
data.PosY = getY()
data.PosZ = getZ()
print "Setting %f, %f, %f " % (data.PosX, data.PosY, data.PosZ)
struct.pack_into(fmt, buff, 0, *[getattr(data,field) for field,typ in data._fields_])
time.sleep(0.05)
if __name__ == "__main__":
main()
我知道我可以创建一个变量到共享内存文件中位置的映射,但是有这么多字段,这有点笨拙。
我想该结构可以是缓冲区(或映射到缓冲区)并且通过简单地设置 data.PosX,共享内存被更新。这可能吗?有什么办法可以提高效率吗? struct.pack_into 是我关心的那一行。
我想这样的事情可以做到:
buff = mmap.mmap(0, ctypes.sizeof(GenericData), "$MyTag$")
data = from_buffer(buff, GenericData)
while (1):
data.posX = getX()
data.posY = getY()
data.posZ = getZ()
time.sleep(0.05)
...然后会更新共享内存。可能吗?
【问题讨论】:
-
你们非常非常亲近。您是否在 ctypes 教程和参考资料中搜索过“from_buffer”?真的很简单:
data = GenericData.from_buffer(buff). -
fileno应该为 -1 用于映射匿名内存。在 Windows 上,mmap 为此允许 0,即使 0 是有效的文件描述符。但是,在未来的版本中,它可能会更新为在 Windows 上使用 0 弃用。 -
@eryksun:谢谢!我知道我很接近 - 不知道我有那么接近!另外,感谢您对文件描述符的 0 与 -1 的清晰说明。您想提供官方答案以便我接受吗? (否则,我会自己回答并引用你)
标签: python ctypes shared-memory