zyx2012 发表于 2025-1-27 20:06:44

BufferError--PythonBIF(8)

本帖最后由 zyx2012 于 2025-1-27 02:08 编辑

看原文:

Help on class BufferError in module builtins:

class BufferError(Exception)
|Buffer error.
|
|Method resolution order:
|      BufferError
|      Exception
|      BaseException
|      object
|
|Methods defined here:
|
|__init__(self, /, *args, **kwargs)
|      Initialize self.See help(type(self)) for accurate signature.
|
|----------------------------------------------------------------------
|Static methods defined here:
|
|__new__(*args, **kwargs)
|      Create and return a new object.See help(type) for accurate signature.
|
|----------------------------------------------------------------------
|Methods inherited from BaseException:
|
|__getattribute__(self, name, /)
|      Return getattr(self, name).
|
|__reduce__(self, /)
|      Helper for pickle.
|
|__repr__(self, /)
|      Return repr(self).
|
|__setstate__(self, object, /)
|
|__str__(self, /)
|      Return str(self).
|
|add_note(self, object, /)
|      Exception.add_note(note) --
|      add a note to the exception
|
|with_traceback(self, object, /)
|      Exception.with_traceback(tb) --
|      set self.__traceback__ to tb and return self.
|
|----------------------------------------------------------------------
|Data descriptors inherited from BaseException:
|
|__cause__
|      exception cause
|
|__context__
|      exception context
|
|__dict__
|
|__suppress_context__
|
|__traceback__
|
|args

翻译:

模块内置程序中有关类 BufferError 的帮助:

类 BufferError(Exception)
| 缓冲区错误。
|
| 方法解析顺序:
| 缓冲错误
| 异常
| 基本异常
| 对象
|
| 这里定义的方法:
|
| __init__(self, /, *args, **kwargs)
| 初始化自身。 有关准确的签名,请参见 help(type(self)) 。
|
| ----------------------------------------------------------------------
| 此处定义的静态方法:
|
| __new__(*args, **kwargs)
| 创建并返回一个新对象。 有关准确的签名,请参见 help(type)。
|
| ----------------------------------------------------------------------
| 继承自 BaseException 的方法:
|
| __getattribute__(self, name, /)
| 返回 getattr(self,name)。
|
| __reduce__(self, /)
| pickle 的辅助函数。
|
| 返回 __repr__(self, /)
| 返回 repr(self)。
|
| __setstate__(self, object, /)
|
|__str__(self, /)
| 返回 str(self)。
|
| add_note(self, object, /)
| Exception.add_note(note) --
| 为异常添加注释
|
| with_traceback(self, object, /)
| Exception.with_traceback(tb) -- | 为异常添加注释。
| 将 self.__traceback__ 设为 tb 并返回 self。
|
| ----------------------------------------------------------------------
| 从 BaseException 继承的数据描述符:
|
| __cause__
| 异常原因
|
| __context__
| 异常上下文
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args


缓冲区错误:通常在缓冲区相关操作无法完成时引发,例如尝试修改一个不可写的缓冲区或者调整已导出数据的缓冲区大小。

示例:


# demo.py
from contextlib import contextmanager
from multiprocessing.managers import SharedMemoryManager
from multiprocessing.shared_memory import SharedMemory
from typing import Iterator
import numpy as np

@contextmanager
def allocate_shared_mem() -> Iterator:
    with SharedMemoryManager() as smm:
      shared_mem = smm.SharedMemory(size=80)
      yield shared_mem

with allocate_shared_mem() as shared_mem:
    shared_arr = np.frombuffer(shared_mem.buf)
    assert len(shared_arr) == 10

问题:

$ python demo.py
Exception ignored in: <function SharedMemory.__del__ at 0x7ff8bf604ee0>
Traceback (most recent call last):
File "/home/rig1/miniconda3/envs/pysc/lib/python3.10/multiprocessing/shared_memory.py", line 184, in __del__
File "/home/rig1/miniconda3/envs/pysc/lib/python3.10/multiprocessing/shared_memory.py", line 227, in close
BufferError: cannot close exported pointers exist


问题在于,当numpy数组存在时,SharedMemoryManager无法释放shared_mem。如果我将del shared_array附加到with块末尾的demo.py底部,那么问题就没有了。

#说实话,我的IDLE卡在那几个小时动不了了(新电脑买了几百块钱的,后悔了),所以上网上找的答案,水平有限,还请谅解!{:5_92:}

FishC 发表于 2025-1-27 20:06:50

问题在于当 numpy数组 仍然存在时,SharedMemoryManager 无法释放 shared_mem。这是因为 numpy数组 还在使用 shared_mem 的缓冲区。你可以通过在 with 块的末尾显式删除 shared_arr 来解决这个问题。

以下是修改后的代码:


# demo.py
from contextlib import contextmanager
from multiprocessing.managers import SharedMemoryManager
from multiprocessing.shared_memory import SharedMemory
from typing import Iterator
import numpy as np

@contextmanager
def allocate_shared_mem() -> Iterator:
    with SharedMemoryManager() as smm:
      shared_mem = smm.SharedMemory(size=80)
      yield shared_mem

with allocate_shared_mem() as shared_mem:
    shared_arr = np.frombuffer(shared_mem.buf, dtype=np.float64)
    assert len(shared_arr) == 10
    del shared_arr# 显式删除 numpy 数组


这样,在 with 块结束之前, shared_arr 会被删除,从而允许 SharedMemoryManager 正常释放 shared_mem。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: BufferError--PythonBIF(8)