您如何在python中将完整结构写入共享内存? [英] How do you write a full struct to shared memory in python?

查看:65
本文介绍了您如何在python中将完整结构写入共享内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有许多示例显示了如何将单个变量甚至结构的单个成员写入共享内存,但是有一种方法可以将整个结构放入共享内存中,以便您可以简单地操作该结构以更新共享内存?

There are plenty of examples showing how to write single variables or even individual members of a struct to shared memory, but is there a way to put the whole struct into shared memory so that you can simply manipulate the struct to update shared memory?

这是到目前为止我正在做的一个示例(在我的实际程序中-结构中有50多个字段-完成时可能超过100个字段).它每0.05秒用x,y,z坐标更新共享内存.尽管它可以正常工作,但它在每个步骤都打包了一个新的结构,并将整个内容写入共享内存-对我来说这似乎效率很低.

This is an example what I'm doing so far (in my actual program - there are over 50 fields in the struct - possibly 100+ by the time I'm done). It updates shared memory with x,y,z coordinates every 0.05 seconds. While it works as it sits, it's packing up a new struct at every step and writing the whole thing to shared memory - which seems inefficient to me.

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()

我知道我可以在共享内存文件中创建变量到位置的映射,但是由于字段太多,这有点麻烦.

I am aware that I could create a mapping of variables to locations in the shared memory file, but with so many fields, that's a little unwieldy.

我想认为该结构可以是缓冲区(或映射到缓冲区),只需设置data.PosX,即可更新共享内存.这可能吗?有什么办法可以提高效率?struct.pack_into行是我关注的那一行.

I would like to think that the struct could be the buffer (or mapped to the buffer) and by simply setting data.PosX, shared memory is updated. Is this possible? Is there any way to make this more efficient? The struct.pack_into line is the one that concerns me.

我想可以这样做:

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)

...然后将更新共享内存.有可能吗?

...which would then update the shared memory. Possible?

推荐答案

正如@eryksun在对该问题的第一条评论中指出的那样,您可以使用 ctypes.from_buffer 共享ctypes结构 GenericData 和mmap缓冲区 buff .@eryksun还指出,尽管Windows允许 0 作为映射匿名内存的文件描述符,但 -1 是正确的值-如文档中所述.

As @eryksun pointed out in the first comment to the question, you can use ctypes.from_buffer to share the ctypes structure GenericData with the mmap buffer buff. @eryksun also pointed out that while Windows allows 0 as a file descriptor to map anonymous memory, -1 is the correct value - as is mentioned in the docs.

有了这个,这是一个有效的示例,已调整为包括@eryksun的答案:

With that, here's a working example, adjusted to include @eryksun's answer:

import ctypes
import mmap
import time
import math

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(-1, ctypes.sizeof(GenericData), "$MyTag$")

    data = GenericData.from_buffer(buff)

    for fname, ftype in data._fields_:
        setattr(data, fname, 0)

    count = 0

    while (1):
        data.PosX = getX()
        data.PosY = getY()
        data.PosZ = getZ()

        print ("Setting %f, %f, %f " % (data.PosX, data.PosY, data.PosZ))
        count += 1
        time.sleep(0.05)


if __name__ == "__main__":
    main()

这篇关于您如何在python中将完整结构写入共享内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆