Author giampaolo.rodola
Recipients brett.cannon, davin, eric.snow, giampaolo.rodola, lukasz.langa, nascheme, osvenskan, pitrou, pmpp, rhettinger, ronaldoussoren, skrah, terry.reedy, yselivanov
Date 2019-02-23.15:40:07
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1550936407.5.0.0820977087216.issue35813@roundup.psfhosted.org>
In-reply-to
Content
> We are consciously choosing to not support an atomic "create or attach".  This significantly simplifies the API and avoids the valid concerns raised around user confusion relating to that behavior (including the use of different specified 'size' values in a race) but does not preclude our potentially introducing this as a feature in the future.

I understand that because of *size* we cannot solve the race condition issue unless the user uses some sort of synchronization mechanism. FWIW I bumped into this lib:
http://semanchuk.com/philip/sysv_ipc/
...which provides two separate APIs to "create" and "attach":

>>> SharedMemory("name", IPC_CREX)
>>> attach("name")

At this point I'm agnostic about the API, which is probably just a matter of personal taste (e.g. one may prefer a separate SharedMemory.attach() classmethod or a *mode* argument accepting "x" and "a"). I see that that lib use shmat() on attach and shmdt() on detach. I'm not sure if that makes a difference, just mentioning it because your implementation doesn't do that on close() and perhaps it should.


> Combined with a SyncManager.Lock, users can already achieve an atomic "create or attach" using this simpler API.

That assumes a single app/process which spawns a child (the "worker"). In that case SyncManager.Lock/others is indeed compatible with SharedMemory and can be used to implement non-racy "create or attach" and also to synchronize memory access on read and write. But AFAICT there are two uses cases for this functionality, and there currently is no mechanism to do any that if you have two unrelated apps/processes relying on a common shared memory *name* and *size*. I'm taking a peek at "man smh_overview" which says:

<<Typically, processes must synchronize their access to a shared memory object, using, for example, POSIX semaphores. System V shared memory (shmget(2), shmop(2), etc.) is an older shared memory API. POSIX shared memory provides a simpler, and better designed interface; on the other hand POSIX shared memory is somewhat less widely available (especially on older systems) than System V shared memory.>>

That would translate into a new Semaphore(name=None, create=False) class which (possibly?) would also provide better performances compared to SyncManager.Semaphore. Not sure if we can do the same on Windows though. 

Extra 1: apparently there are also POSIX msgget(), msgrcv() and msgsnd() syscalls which could be used to implement a System-V message Queue similar to SyncManager.Queue later on. 

Extra 2: given the 2 distinct use-cases I wonder if the low-level component (shared_memory.py) really belongs to multiprocessing module. Perhaps this should be provided as a separate "sharedmemory" module with multiprocessing.managers.SharedMemoryMemory being the high-level interface.
History
Date User Action Args
2019-02-23 15:40:07giampaolo.rodolasetrecipients: + giampaolo.rodola, brett.cannon, nascheme, rhettinger, terry.reedy, ronaldoussoren, pitrou, osvenskan, skrah, pmpp, lukasz.langa, eric.snow, yselivanov, davin
2019-02-23 15:40:07giampaolo.rodolasetmessageid: <1550936407.5.0.0820977087216.issue35813@roundup.psfhosted.org>
2019-02-23 15:40:07giampaolo.rodolalinkissue35813 messages
2019-02-23 15:40:07giampaolo.rodolacreate