This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2011年07月14日 18:00 by zolnie, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Messages (7) | |||
|---|---|---|---|
| msg140349 - (view) | Author: Piotr Zolnierczuk (zolnie) | Date: 2011年07月14日 18:00 | |
Hi, I am trying to migrate from Python 2.5 to Python 2.7 I found though the mmap behaves differently on Windows XP between the two versions. It boils down to the following code: import mmap map1 = mmap.mmap(fileno=0, tagname='MyData', length=4096) map2 = mmap.mmap(fileno=0, tagname='MyData', length=8192) It runs fine (so I can "resize" shared memory) on XP with 2.5.4, but when running on 2.7.2 I get the following error Traceback (most recent call last): File "D:\Workspace\memmap_test.py", line 3, in <module> map2 = mmap.mmap(fileno=0, tagname='MyData', length=8192) WindowsError: [Error 5] Access is denied |
|||
| msg141482 - (view) | Author: Vlad Riscutia (vladris) | Date: 2011年07月31日 23:05 | |
Reason you are seeing the failure for this is following change from 2.5 in mmapmodule.c (:1109): m_obj->data = (char *) MapViewOfFile(m_obj->map_handle, dwDesiredAccess, 0, 0, 0); changed to mmapmodule.c (:1414 in 3.3): m_obj->data = (char *) MapViewOfFile(m_obj->map_handle, dwDesiredAccess, off_hi, off_lo, m_obj->size); Previously size wasn't passed to MapViewOfFile. Passing new size to MapViewOfFile greater than the size of previous map causes an error. This seems to be by design. From MSDN: MapViewOfFile: dwNumberOfBytesToMap [in] The number of bytes of a file mapping to map to the view. All bytes must be within the maximum size specified by CreateFileMapping. If this parameter is 0 (zero), the mapping extends from the specified offset to the end of the file mapping. CreateFileMapping: lpName [in, optional] The name of the file mapping object. If this parameter matches the name of an existing mapping object, the function requests access to the object with the protection that flProtect specifies. So on second call, CreateFileMapping will get back the previous mapping object, which has 4096 bytes of memory mapped. MapViewOfFile will try to map beyond its limit and get an error. I am curious how "resizing" worked before. I tried passing size=0 to MapViewOfFile on second call (length=8192) then call VirtualQuery on the returned map, which can query the size of the buffer. Size is still 4096. So even if length=8192 and we call CreateFileMapping with this length, it will return the previous 4096 byte-buffer. This looks to me like an issue which existed until Python 2.5, namely this error was silenced and returned map was still 4096 bytes, just claiming to be 8192. The way it is behaving now seems to be the correct way. |
|||
| msg141508 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2011年08月01日 13:28 | |
Vlad, thank you for the diagnosis. Indeed by passing a different tagname (or no tagname at all), the problem doesn't occur. Since mmap.mmap() matches the semantics chosen by Microsoft here, I tend to think this is not a bug; besides, "fixing" it would probably be intricate. |
|||
| msg141517 - (view) | Author: Piotr Zolnierczuk (zolnie) | Date: 2011年08月01日 14:30 | |
OK. I will work around it. I was using 'mapping object of a specified size that is backed by the system paging file instead of by a file in the file system' - map->handle == INVALID_HANDLE_VALUE (-1), i.e. shared memory for inter-process communication (not my choice) A use case was when all process were stopped and one wanted to start "fresh" using the same tag but with a bigger size. BTW, here's the result of the following script in Python 2.5 >>> import mmap >>> map1 = mmap.mmap(fileno=-1, tagname='MyData', length=4096) >>> map1[0] = 'a' >>> map1[4095]='b' >>> print len(map1), map1[0], map1[4095] 4096 a b >>> map2 = mmap.mmap(fileno=-1, tagname='MyData', length=8192) >>> print len(map2), map2[0], map2[4095] 8192 a b which would indicate that it does 'resize' and preserves the data. which means t |
|||
| msg141519 - (view) | Author: Piotr Zolnierczuk (zolnie) | Date: 2011年08月01日 14:38 | |
Just looked into my "partner" C++ code and he's using it very much like in Python 2.5: m_obj->map_handle = CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, pageSize, tagName); m_obj->data = (char *) MapViewOfFile (m_obj->map_handle, FILE_MAP_ALL_ACCESS, 0, 0, 0); |
|||
| msg141520 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2011年08月01日 14:41 | |
Note that multiprocessing can abstract this kind of things for you: http://docs.python.org/library/multiprocessing#sharing-state-between-processes http://docs.python.org/library/multiprocessing#module-multiprocessing.sharedctypes |
|||
| msg404856 - (view) | Author: Tim Golden (tim.golden) * (Python committer) | Date: 2021年10月23日 07:15 | |
(switching stage to resolved because it's closed/rejected; sorry for the noise) |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:19 | admin | set | github: 56771 |
| 2021年10月23日 07:15:19 | tim.golden | set | messages:
+ msg404856 stage: resolved |
| 2011年08月01日 14:42:58 | pitrou | set | status: open -> closed |
| 2011年08月01日 14:41:31 | pitrou | set | messages: + msg141520 |
| 2011年08月01日 14:38:56 | zolnie | set | messages: + msg141519 |
| 2011年08月01日 14:30:01 | zolnie | set | status: pending -> open messages: + msg141517 |
| 2011年08月01日 13:28:36 | pitrou | set | status: open -> pending resolution: rejected messages: + msg141508 versions: + Python 3.2, Python 3.3 |
| 2011年07月31日 23:05:39 | vladris | set | nosy:
+ vladris messages: + msg141482 |
| 2011年07月29日 12:59:22 | pitrou | set | nosy:
+ pitrou, tim.golden, brian.curtin |
| 2011年07月14日 18:00:42 | zolnie | set | type: behavior components: + Windows |
| 2011年07月14日 18:00:02 | zolnie | create | |