単一変数や構造体の個々のメンバーを共有メモリに書き込む方法を示す例はたくさんありますが、構造体全体を共有メモリに入れて共有メモリを更新するために単純に構造体を操作できる方法はありますか?Pythonで共有メモリに完全な構造体を書く方法はありますか?
これは私がこれまで行っていることの例です(私の実際のプログラムでは、構造体に50以上のフィールドがあります。 x、y、z座標で共有メモリを0.05秒ごとに更新します。それが座っているように動作しますが、それはすべてのステップで新しい構造体を詰め込み、すべてを共有メモリに書き込んでいます。これは私にとって非効率的です。
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)'。 – eryksun
'fileno'は匿名メモリをマッピングするために-1になります。 Windowsでは、0が有効なファイル記述子であっても、mmapはこれを0にします。ただし、将来のバージョンでは、Windowsで0を使用して非推奨に更新される可能性があります。 – eryksun
@eryksun:ありがとう!私は私が近くにいることを知っていた - 私はそれが近いことを知らなかった!また、ファイルディスクリプタの0と-1についての明確さについてもありがとうございます。私はそれを受け入れることができるように正式な回答を提供したいですか? (そうでなければ、私は自分自身に答えて、あなたを引用します) –