Python, mmap, что если я не вызову mmap.close () вручную? - PullRequest
0 голосов
/ 22 мая 2018

Я пришел из мира C ++ / RAII.

Так что мне кажется смущенным, когда и как вызывать mmap.close () [не file.close ()].

Или вообще не звонить?Будет ли утечка?

Что касается примера кода из документа ;
, что делать, если я хочу использовать буфер 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 Ответ

0 голосов
/ 22 мая 2018

Глядя на источник mmapmodule.c , файл не сопоставляется и закрывается, когда счетчик ссылок на объект обнуляется и удаляется.Следующая функция находится в объекте 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);
}
...