鱼C论坛

 找回密码
 立即注册
查看: 227|回复: 1

[技术交流] BufferError--PythonBIF(8)

[复制链接]
发表于 2025-1-27 20:06:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

看原文:

  1. Help on class BufferError in module builtins:

  2. class BufferError(Exception)
  3. |  Buffer error.
  4. |
  5. |  Method resolution order:
  6. |      BufferError
  7. |      Exception
  8. |      BaseException
  9. |      object
  10. |
  11. |  Methods defined here:
  12. |
  13. |  __init__(self, /, *args, **kwargs)
  14. |      Initialize self.  See help(type(self)) for accurate signature.
  15. |
  16. |  ----------------------------------------------------------------------
  17. |  Static methods defined here:
  18. |
  19. |  __new__(*args, **kwargs)
  20. |      Create and return a new object.  See help(type) for accurate signature.
  21. |
  22. |  ----------------------------------------------------------------------
  23. |  Methods inherited from BaseException:
  24. |
  25. |  __getattribute__(self, name, /)
  26. |      Return getattr(self, name).
  27. |
  28. |  __reduce__(self, /)
  29. |      Helper for pickle.
  30. |
  31. |  __repr__(self, /)
  32. |      Return repr(self).
  33. |
  34. |  __setstate__(self, object, /)
  35. |
  36. |  __str__(self, /)
  37. |      Return str(self).
  38. |
  39. |  add_note(self, object, /)
  40. |      Exception.add_note(note) --
  41. |      add a note to the exception
  42. |
  43. |  with_traceback(self, object, /)
  44. |      Exception.with_traceback(tb) --
  45. |      set self.__traceback__ to tb and return self.
  46. |
  47. |  ----------------------------------------------------------------------
  48. |  Data descriptors inherited from BaseException:
  49. |
  50. |  __cause__
  51. |      exception cause
  52. |
  53. |  __context__
  54. |      exception context
  55. |
  56. |  __dict__
  57. |
  58. |  __suppress_context__
  59. |
  60. |  __traceback__
  61. |
  62. |  args
复制代码

翻译:

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

  2. 类 BufferError(Exception)
  3. | 缓冲区错误。
  4. |
  5. | 方法解析顺序:
  6. | 缓冲错误
  7. | 异常
  8. | 基本异常
  9. | 对象
  10. |
  11. | 这里定义的方法:
  12. |
  13. | __init__(self, /, *args, **kwargs)
  14. | 初始化自身。 有关准确的签名,请参见 help(type(self)) 。
  15. |
  16. | ----------------------------------------------------------------------
  17. | 此处定义的静态方法:
  18. |
  19. | __new__(*args, **kwargs)
  20. | 创建并返回一个新对象。 有关准确的签名,请参见 help(type)。
  21. |
  22. | ----------------------------------------------------------------------
  23. | 继承自 BaseException 的方法:
  24. |
  25. | __getattribute__(self, name, /)
  26. | 返回 getattr(self,name)。
  27. |
  28. | __reduce__(self, /)
  29. | pickle 的辅助函数。
  30. |
  31. | 返回 __repr__(self, /)
  32. | 返回 repr(self)。
  33. |
  34. | __setstate__(self, object, /)
  35. |
  36. |__str__(self, /)
  37. | 返回 str(self)。
  38. |
  39. | add_note(self, object, /)
  40. | Exception.add_note(note) --
  41. | 为异常添加注释
  42. |
  43. | with_traceback(self, object, /)
  44. | Exception.with_traceback(tb) -- | 为异常添加注释。
  45. | 将 self.__traceback__ 设为 tb 并返回 self。
  46. |
  47. | ----------------------------------------------------------------------
  48. | 从 BaseException 继承的数据描述符:
  49. |
  50. | __cause__
  51. | 异常原因
  52. |
  53. | __context__
  54. | 异常上下文
  55. |
  56. | __dict__
  57. |
  58. | __suppress_context__
  59. |
  60. | __traceback__
  61. |
  62. | args
复制代码


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

示例:


  1. # demo.py
  2. from contextlib import contextmanager
  3. from multiprocessing.managers import SharedMemoryManager
  4. from multiprocessing.shared_memory import SharedMemory
  5. from typing import Iterator
  6. import numpy as np

  7. @contextmanager
  8. def allocate_shared_mem() -> Iterator[SharedMemory]:
  9.     with SharedMemoryManager() as smm:
  10.         shared_mem = smm.SharedMemory(size=80)
  11.         yield shared_mem

  12. with allocate_shared_mem() as shared_mem:
  13.     shared_arr = np.frombuffer(shared_mem.buf)
  14.     assert len(shared_arr) == 10
复制代码

问题:

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


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

#说实话,我的IDLE卡在那几个小时动不了了(新电脑买了几百块钱的,后悔了),所以上网上找的答案,水平有限,还请谅解!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-1-27 20:06:50 | 显示全部楼层
问题在于当 numpy数组 仍然存在时,SharedMemoryManager 无法释放 shared_mem。这是因为 numpy数组 还在使用 shared_mem 的缓冲区。你可以通过在 [c]with[/c] 块的末尾显式删除 shared_arr 来解决这个问题。

以下是修改后的代码:


  1. # demo.py
  2. from contextlib import contextmanager
  3. from multiprocessing.managers import SharedMemoryManager
  4. from multiprocessing.shared_memory import SharedMemory
  5. from typing import Iterator
  6. import numpy as np

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

  12. with allocate_shared_mem() as shared_mem:
  13.     shared_arr = np.frombuffer(shared_mem.buf, dtype=np.float64)
  14.     assert len(shared_arr) == 10
  15.     del shared_arr  # 显式删除 numpy 数组
复制代码


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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-6 02:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表