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)