Windows -> WSL間でMMAPをやろうとしたけどうまくいかなかったので、ファイル経由でデータの受け渡しをした

Windows -> WSL間で画像データの受け渡しをしたかったので、MMAPを使ってプロセス間通信をしようとしたが、結局うまくいかなかった。代替策としてファイル経由でデータの受け渡しをした。RAMDISKを使用したのでそれなりに速度は出る、と思う。

やったこと

データ受け渡しのテストとして、Windows側から乱数を書き込み、WSL側で読み取るというテストをした。MMAPを使うソースコードは以下の通り。

  • 送信側
import mmap
import time
import random

with open("hello.txt", "r+b") as f:
    mm = mmap.mmap(f.fileno(), 0)
    while True:
        i = random.randint(50, 100)
        mm[:] = i.to_bytes(2, 'little')
        print(i)        
        time.sleep(1)
  • 受信側
import mmap, time

with open("hello.txt", "r+b") as f:
    mm = mmap.mmap(f.fileno(), 0)
    while True:
        mm.seek(0)
        print(int.from_bytes(mm.read(), 'little')) 
        time.sleep(1)
    mm.close()

それぞれ実行して、Printされる文字列が同じであればいい。

コードの確認もかねて、組み合わせを変えてやった結果は以下の通り。

  • 送信:Windows、受信:Windows
    • 成功
  • 送信:WSL、受信:WSL
    • 成功
  • 送信:Windows、受信:WSL
    • 失敗(WSL側で実行開始した時点のデータからずっと更新されない)
  • 送信:WSL、受信:Windows
    • 失敗(Windows側で実行開始した時点のデータからずっと更新されない)

原因

WSLはOSより下のHyper-vの上で動いていて、そこでメモリ空間も分けられている。MMAPはOS上のリソースをメモリ上にマッピングする関数で、例えば上記ではhello.txtをメモリ上のAという場所にマッピングする。しかしHyper-v経由ではAにアクセスできないので、新たにBという場所にマッピングされる。そのため値が変化しないままなのではないかと思われる。

対処法

MMAPは使えないので、単純にファイル経由での受け渡しにした。これで値が変化するようになった。そのままだとストレージを経由するので、RAMDISKを作ってRAMDISK経由にすれば、速度はより高速になるのではないかと思われる。(そこまで早くならないという情報もあり)

ImDisk Toolkit download | SourceForge.net

  • 送信側
import time
import random

with open("R:\hello.txt", "w+b") as f:
    while True:
        i = random.randint(50, 100)
        f.write(i.to_bytes(2, 'little'))
        f.flush()
        print(i)
        f.seek(0)
        
        time.sleep(1)
  • 受信側
import time

with open("/mnt/r/hello.txt", "r+b") as f:
    while True:
        print(int.from_bytes(f.read(), 'little')) 
        time.sleep(1)