代码之家  ›  专栏  ›  技术社区  ›  caoanan

python,mmap,如果我不手动调用mmap.close()呢?

  •  1
  • caoanan  · 技术社区  · 7 年前

    我来自C++/RAII世界。

    所以在何时以及如何调用mmap.close()这一点上我似乎很困惑。 [不是file.close()]。

    或者根本不打电话?会有泄漏吗?

    至于来自 document ;
    如果我想在current模块外使用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()
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   tdelaney    7 年前

    看看 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);
    }