概要
Python3.8から導入されたmultiprocessingモジュールのSharedMemoryによって共有メモリが使えるようになった。
しかし、Windows上では問題なかったが、Linux上でメモリが解放されていないような...。
SharedMemoryの公式HPはこちら。
エラー内容の例
プロセス1(proc1.py)で共有メモリ作成、及びデータを格納し、プロセス2(proc2.py)でプロセス1が格納したデータを取得。
まずはソースコードから。
proc1.py
import pickle
import sys
from multiprocessing import shared_memory
# SharedMemory新規作成
try:
shm = shared_memory.SharedMemory(create=True, size=30, name="test")
except:
print("メモリ作成エラー")
sys.exit(1)
# データ格納
while True:
brother = {
"1": "taro",
"2": "jiro",
"3": "saburo"
}
data = pickle.dumps(brother)
shm.buf[:len(data)] = data
proc2.py
"""
プロセス2での処理
"""
import pickle
import time
import sys
from multiprocessing import shared_memory
start = time.time()
while True:
try:
shm = shared_memory.SharedMemory(name="test")
except:
print("取得エラー")
break
else:
try:
data = pickle.loads(shm.buf)
except pickle.UnpickingError:
continue
except:
print("読み込みエラー")
sys.exit(1)
else:
if time.time() - start > 5:
shm.close()
#shm.unlink()
print("close")
break
この例では、プロセス2が起動5秒後に処理終了。
その際、**shm.close()**でメモリを解放してよかったね!となるはずだが、
こんなUserWarningが出現。
UserWarning: resource_tracker: There appear to be 1 leaked shared_memory objects to clean up at shutdown
warnings.warn(‘resource_tracker: There appear to be %d ‘
shm.closeでメモリ解放がされてないらしく、プロセス2をもう一度動かしてみると、メモリを取得不可(取得エラーと出力される)。
ついでに公式にあったもう1つのshm.unlinkも実行。
当然unlinkと言う名前の通りリンクを切るため、再度プロセス2を実行しても取得できるわけもなく。
また、これも当然の話ですがプロセス1を再起動したら、再び取得可能。
まとめ
SharedMemoryのcloseがLinux上でうまく動いてなさそう。
共有メモリはまだPython&Linuxではやらない方が良いかも。
その他
GitHubに載せています。