简体   繁体   中英

Free memory in shared memory dict

I use shared_memory_dict https://pypi.org/project/shared-memory-dict/ I have a class, that create a shared memory dict inside

class A:
    def __init__(self, id):
        self.smd = SharedMemoryDict(name=id, size=1024)
    def update(self, i):
        self.smd[i] = i+1
    def clean(self):
        self.smd.shm.close()
        self.smd.shm.unlink()
        del self.smd

I create a shared memory dict to manager all instances of my class

d = SharedMemoryDict(name='dict', size=1024)
for i in range(10):
    d[i] = A(i)
for i in range(5):
    d[i].update(i)

Then i want to delete an item in my dict. I try 2 ways:

  1. Delete directly d[0], the shared memory inside is not be close and unlink
del d[0]
  1. Free shared memory first, then delete item. It leads to error below:
d[0].clean()
del d[0]
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Input In [6], in <cell line: 2>()
      1 d[0].clean()
----> 2 del d[0]

File /opt/anaconda/envs/python38/lib/python3.8/site-packages/shared_memory_dict/dict.py:102, in SharedMemoryDict.__delitem__(self, key)
    101 def __delitem__(self, key: str) -> None:
--> 102     with self._modify_db() as db:
    103         del db[key]

File /opt/anaconda/envs/python38/lib/python3.8/contextlib.py:113, in _GeneratorContextManager.__enter__(self)
    111 del self.args, self.kwds, self.func
    112 try:
--> 113     return next(self.gen)
    114 except StopIteration:
    115     raise RuntimeError("generator didn't yield") from None

File /opt/anaconda/envs/python38/lib/python3.8/site-packages/shared_memory_dict/dict.py:87, in SharedMemoryDict._modify_db(self)
     84 @contextmanager
     85 @lock
     86 def _modify_db(self) -> Generator:
---> 87     db = self._read_memory()
     88     yield db
     89     self._save_memory(db)

File /opt/anaconda/envs/python38/lib/python3.8/site-packages/shared_memory_dict/dict.py:184, in SharedMemoryDict._read_memory(self)
    183 def _read_memory(self) -> Dict[str, Any]:
--> 184     return self._serializer.loads(self._memory_block.buf.tobytes())

File /opt/anaconda/envs/python38/lib/python3.8/site-packages/shared_memory_dict/serializers.py:50, in PickleSerializer.loads(self, data)
     48 def loads(self, data: bytes) -> dict:
     49     try:
---> 50         return pickle.loads(data)
     51     except pickle.UnpicklingError:
     52         raise DeserializationError(data)

File /opt/anaconda/envs/python38/lib/python3.8/multiprocessing/shared_memory.py:102, in SharedMemory.__init__(self, name, create, size)
    100 else:
    101     name = "/" + name if self._prepend_leading_slash else name
--> 102     self._fd = _posixshmem.shm_open(
    103         name,
    104         self._flags,
    105         mode=self._mode
    106     )
    107     self._name = name
    108 try:

FileNotFoundError: [Errno 2] No such file or directory: '/sm_0'

What is the proper way to delete that item?

I found a solution. Instead of creating share memory inside a class, I create share memory outside and just pass its name to initiate the class. The update() function need to load existing memory, update its value and close(). Then I can delete the instance and free the shared memory outside with no error

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM