Python,mmap,如果我不手动调用mmap.close()怎么办?
Python, mmap, what if I don't call mmap.close() manually?
我来自 C++/RAII 世界。
所以我对何时以及如何调用 mmap.close() 感到困惑
[不是 file.close()]。
或者,根本不调用它?会不会漏电?
至于示例代码来自document;
如果我想在当前模块外使用 mmap 缓冲区怎么办,
而不是在最后一行就地关闭它?
import mmap
# write a simple example file
with open("hello.txt", "wb") as f:
f.write("Hello Python!\n")
with open("hello.txt", "r+b") as f:
# memory-map the file, size 0 means whole file
mm = mmap.mmap(f.fileno(), 0)
# read content via standard file methods
print mm.readline() # prints "Hello Python!"
# read content via slice notation
print mm[:5] # prints "Hello"
# update content using slice notation;
# note that new content must have same size
mm[6:] = " world!\n"
# ... and read again using standard file methods
mm.seek(0)
print mm.readline() # prints "Hello world!"
# close the map
mm.close()
查看 mmapmodule.c source,当对象引用计数变为零并删除文件时,文件将取消映射并关闭。以下函数在对象的 tp_dealloc
中。这类似于源代码中的 close
方法,这意味着您所要做的就是退出引用地图或 del
它们的任何变量的范围。
所有这些都有一个警告。如果你有 python 垃圾收集器无法解决的循环引用,引用计数将永远不会变为零,资源也不会被清理。注意那些反向引用!
第二个警告 - 我指的是 CPython。谁知道其他实现的核心隐藏着什么。
static void
mmap_object_dealloc(mmap_object *m_obj)
{
#ifdef MS_WINDOWS
if (m_obj->data != NULL)
UnmapViewOfFile (m_obj->data);
if (m_obj->map_handle != NULL)
CloseHandle (m_obj->map_handle);
if (m_obj->file_handle != INVALID_HANDLE_VALUE)
CloseHandle (m_obj->file_handle);
if (m_obj->tagname)
PyMem_Free(m_obj->tagname);
#endif /* MS_WINDOWS */
#ifdef UNIX
if (m_obj->fd >= 0)
(void) close(m_obj->fd);
if (m_obj->data!=NULL) {
munmap(m_obj->data, m_obj->size);
}
#endif /* UNIX */
if (m_obj->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) m_obj);
Py_TYPE(m_obj)->tp_free((PyObject*)m_obj);
}
我来自 C++/RAII 世界。
所以我对何时以及如何调用 mmap.close() 感到困惑 [不是 file.close()]。
或者,根本不调用它?会不会漏电?
至于示例代码来自document;
如果我想在当前模块外使用 mmap 缓冲区怎么办,
而不是在最后一行就地关闭它?
import mmap
# write a simple example file
with open("hello.txt", "wb") as f:
f.write("Hello Python!\n")
with open("hello.txt", "r+b") as f:
# memory-map the file, size 0 means whole file
mm = mmap.mmap(f.fileno(), 0)
# read content via standard file methods
print mm.readline() # prints "Hello Python!"
# read content via slice notation
print mm[:5] # prints "Hello"
# update content using slice notation;
# note that new content must have same size
mm[6:] = " world!\n"
# ... and read again using standard file methods
mm.seek(0)
print mm.readline() # prints "Hello world!"
# close the map
mm.close()
查看 mmapmodule.c source,当对象引用计数变为零并删除文件时,文件将取消映射并关闭。以下函数在对象的 tp_dealloc
中。这类似于源代码中的 close
方法,这意味着您所要做的就是退出引用地图或 del
它们的任何变量的范围。
所有这些都有一个警告。如果你有 python 垃圾收集器无法解决的循环引用,引用计数将永远不会变为零,资源也不会被清理。注意那些反向引用!
第二个警告 - 我指的是 CPython。谁知道其他实现的核心隐藏着什么。
static void
mmap_object_dealloc(mmap_object *m_obj)
{
#ifdef MS_WINDOWS
if (m_obj->data != NULL)
UnmapViewOfFile (m_obj->data);
if (m_obj->map_handle != NULL)
CloseHandle (m_obj->map_handle);
if (m_obj->file_handle != INVALID_HANDLE_VALUE)
CloseHandle (m_obj->file_handle);
if (m_obj->tagname)
PyMem_Free(m_obj->tagname);
#endif /* MS_WINDOWS */
#ifdef UNIX
if (m_obj->fd >= 0)
(void) close(m_obj->fd);
if (m_obj->data!=NULL) {
munmap(m_obj->data, m_obj->size);
}
#endif /* UNIX */
if (m_obj->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) m_obj);
Py_TYPE(m_obj)->tp_free((PyObject*)m_obj);
}