mmapでバイト列を分割して目的のデータを取得する改良

お疲れ様です。

昨日mmapを使った共有メモリでのプロセス間データ共有について記事を書いていました。その補足というかちょっとした改良を考えたのでメモ的に残しておきます。 fallpoke-tech.hatenadiary.jp

内容としては、昨日の記事の中で書いた読取側でバイト列から目的のデータを取り出す部分で長さを直接スライスで指定して取得していた部分の改良になります。このままの書き方ではデータのサイズが変わった時に直接この部分のインデックス指定を書き換えないといけないと思います。

  • 記事の引用

    読み取ったバイト列をスライスで画像データ/幅/高さの該当部分を切り出します。(ここもうちょっとスマートな方法があれば教えてほしい…。)

  • 該当のコード

# バイト列から目的のデータを抽出
byte_img = byte_data[:6000] 
byte_w = byte_data[6000:6004] 
byte_h = byte_data[6004:6008] 


改良版コード

ソースコードの全体はこちらに残してありますので必要があればご確認ください。

github.com

改良の内容としては単純で、確保するメモリ領域の長さを多めにとり、送信元コードで複数データを1つのバイト列に結合する際に区切り文字列終端文字列を追加する方法です。(なんで昨日思いつかなかったんだろう…。)

送信元

  • 確保するメモリ領域の長さを多めにとる(今回は600000に設定)
LENGTH = 600000

mm = mmap(-1, LENGTH, "test_memory")
  • バイト列への結合の際に区切りと終端を識別する文字列を追加して書き込み
    今回は<SEP><END>という名前のバイナリ文字列で追加しています。この部分は目的の文字列に含まれる文字列と被らなければOKです。
# 区切り文字列と終端文字列を追加して1つのバイト列にする  
byte_data = b"<SEP>".join([byte_img, byte_w, byte_h]) + b"<END>"

# メモリに書き込み
mm.write(byte_data)

受取元

確保したメモリ領域全てを読み取り、終端文字列まで切り出した後、区切り文字列で分割しています。

# 共有メモリからバイト列を読み込み
byte_data = mm.read(LENGTH)
    
# 終端文字列までを取得
byte_data = byte_data.split(b"<END>")[0]
# 区切り文字で分割して分けて目的のデータを抽出
byte_img, byte_w, byte_h = byte_data.split(b"<SEP>")