Like SyncManager but uses SharedMemoryServer instead of Server. It provides methods for creating and returning SharedMemory instances and for creating a list-like object (ShareableList) backed by shared memory. It also provides methods that create and return Proxy Objects
| 1374 | |
| 1375 | |
| 1376 | class SharedMemoryManager(BaseManager): |
| 1377 | """Like SyncManager but uses SharedMemoryServer instead of Server. |
| 1378 | |
| 1379 | It provides methods for creating and returning SharedMemory instances |
| 1380 | and for creating a list-like object (ShareableList) backed by shared |
| 1381 | memory. It also provides methods that create and return Proxy Objects |
| 1382 | that support synchronization across processes (i.e. multi-process-safe |
| 1383 | locks and semaphores). |
| 1384 | """ |
| 1385 | |
| 1386 | _Server = SharedMemoryServer |
| 1387 | |
| 1388 | def __init__(self, *args, **kwargs): |
| 1389 | if os.name == "posix": |
| 1390 | # bpo-36867: Ensure the resource_tracker is running before |
| 1391 | # launching the manager process, so that concurrent |
| 1392 | # shared_memory manipulation both in the manager and in the |
| 1393 | # current process does not create two resource_tracker |
| 1394 | # processes. |
| 1395 | from . import resource_tracker |
| 1396 | resource_tracker.ensure_running() |
| 1397 | BaseManager.__init__(self, *args, **kwargs) |
| 1398 | util.debug(f"{self.__class__.__name__} created by pid {getpid()}") |
| 1399 | |
| 1400 | def __del__(self): |
| 1401 | util.debug(f"{self.__class__.__name__}.__del__ by pid {getpid()}") |
| 1402 | |
| 1403 | def get_server(self): |
| 1404 | 'Better than monkeypatching for now; merge into Server ultimately' |
| 1405 | if self._state.value != State.INITIAL: |
| 1406 | if self._state.value == State.STARTED: |
| 1407 | raise ProcessError("Already started SharedMemoryServer") |
| 1408 | elif self._state.value == State.SHUTDOWN: |
| 1409 | raise ProcessError("SharedMemoryManager has shut down") |
| 1410 | else: |
| 1411 | raise ProcessError( |
| 1412 | "Unknown state {!r}".format(self._state.value)) |
| 1413 | return self._Server(self._registry, self._address, |
| 1414 | self._authkey, self._serializer) |
| 1415 | |
| 1416 | def SharedMemory(self, size): |
| 1417 | """Returns a new SharedMemory instance with the specified size in |
| 1418 | bytes, to be tracked by the manager.""" |
| 1419 | with self._Client(self._address, authkey=self._authkey) as conn: |
| 1420 | sms = shared_memory.SharedMemory(None, create=True, size=size) |
| 1421 | try: |
| 1422 | dispatch(conn, None, 'track_segment', (sms.name,)) |
| 1423 | except BaseException as e: |
| 1424 | sms.unlink() |
| 1425 | raise e |
| 1426 | return sms |
| 1427 | |
| 1428 | def ShareableList(self, sequence): |
| 1429 | """Returns a new ShareableList instance populated with the values |
| 1430 | from the input sequence, to be tracked by the manager.""" |
| 1431 | with self._Client(self._address, authkey=self._authkey) as conn: |
| 1432 | sl = shared_memory.ShareableList(sequence) |
| 1433 | try: |
no outgoing calls
searching dependent graphs…