![](/img/trans.png)
[英]segmentation fault (exit code 139 (interrupted by signal 11: SIGSEGV)) when using multiprocessing.shared_memory.ShareMemory in Python
[英]Segmentation Fault using Python Shared Memory
函數store_in_shm
將一個 numpy 數組寫入共享內存,而第二個函數read_from_shm
使用同一共享內存空間中的數據創建一個 numpy 數組並返回 numpy 數組。
但是,在 Python 3.8 中運行代碼會出現以下分段錯誤:
zsh:分段錯誤 python foo.py
為什么從函數read_from_shm
內部訪問 numpy 數組沒有問題,但是在函數外再次訪問 numpy 數組時出現分段錯誤?
輸出:
From read_from_shm(): [0 1 2 3 4 5 6 7 8 9]
zsh: segmentation fault python foo.py
% /Users/athena/opt/anaconda3/envs/test/lib/python3.8/multiprocessing/resource_tracker.py:203: 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 '
文件
import numpy as np
from multiprocessing import shared_memory
def store_in_shm(data):
shm = shared_memory.SharedMemory(name='foo', create=True, size=data.nbytes)
shmData = np.ndarray(data.shape, dtype=data.dtype, buffer=shm.buf)
shmData[:] = data[:]
shm.close()
return shm
def read_from_shm(shape, dtype):
shm = shared_memory.SharedMemory(name='foo', create=False)
shmData = np.ndarray(shape, dtype, buffer=shm.buf)
print('From read_from_shm():', shmData)
return shmData
if __name__ == '__main__':
data = np.arange(10)
shm = store_in_shm(data)
shmData = read_from_shm(data.shape, data.dtype)
print('From __main__:', shmData) # no seg fault if we comment this line
shm.unlink()
基本上問題似乎是當函數返回時shm
被垃圾收集時,底層的 mmap'ed 文件(由shm
在read_from_shm
擁有)正在關閉。 然后shmData
指回它,這是您獲得段錯誤的地方(用於指代關閉的 mmap)這似乎是一個已知錯誤,但可以通過保留對shm
的引用來解決。
此外,所有SharedMemory
實例都希望close()
'd,其中一個在不再需要時被unlink()
'ed。 如果你自己不調用shm.close()
,它會在前面提到的 GC 中調用,在 Windows 上,如果它是當前“打開”的唯一一個,則共享內存文件將被刪除。 當您在store_in_shm
調用shm.close()
,您會引入操作系統依賴項,因為在 Windows 上數據將被刪除,而 MacOS 和 Linux 將保留直到調用unlink
。
最后,盡管這不會出現在您的代碼中,但當前存在另一個問題,即從獨立進程(而不是子進程)訪問數據可能會過早地刪除底層 mmap。 SharedMemory
是一個非常新的庫,希望所有問題都能很快解決。
您可以重寫給定的示例以保留對“第二個” shm
的引用,只需使用其中一個即可unlink
:
import numpy as np
from multiprocessing import shared_memory
def store_in_shm(data):
shm = shared_memory.SharedMemory(name='foo', create=True, size=data.nbytes)
shmData = np.ndarray(data.shape, dtype=data.dtype, buffer=shm.buf)
shmData[:] = data[:]
#there must always be at least one `SharedMemory` object open for it to not
# be destroyed on Windows, so we won't `shm.close()` inside the function,
# but rather after we're done with everything.
return shm
def read_from_shm(shape, dtype):
shm = shared_memory.SharedMemory(name='foo', create=False)
shmData = np.ndarray(shape, dtype, buffer=shm.buf)
print('From read_from_shm():', shmData)
return shm, shmData #we need to keep a reference of shm both so we don't
# segfault on shmData and so we can `close()` it.
if __name__ == '__main__':
data = np.arange(10)
shm1 = store_in_shm(data)
#This is where the *Windows* previously reclaimed the memory resulting in a
# FileNotFoundError because the tempory mmap'ed file had been released.
shm2, shmData = read_from_shm(data.shape, data.dtype)
print('From __main__:', shmData)
shm1.close()
shm2.close()
#on windows "unlink" happens automatically here whether you call `unlink()` or not.
shm2.unlink() #either shm1 or shm2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.