欣赏一个尚未关闭的python运行时bug

这是一个语言的运行时错误,在linux环境,跨语言使用共享内存时,会触发。它会在python程序退出时,自行销毁sharedMemory,即便此时还有其他的进程在使用——这会让C/Python跨进程调用几乎没有办法进行。

python程序运行完毕会弹出错误信息:

UserWarning: resource_tracker: There appear to be 1 leaked shared_memory objects to clean up at shutdown

然后你定义的sharedMemory就被python随手析构了。如果涉及C调用python,与共享内存相关的数据只能读,无法从python传出——因为python会析构它。共享内存本来就是为了在进程间高效传递二进制参数和运算结果的——这个bug会这类跨进程协同的设计无法进行。

python语言维护群组,对这个问题的相关原始讨论参见下面代码中的注释中的那个链接地址。现有的python发行版本中还没有消除这个bug——因为有一些其他的关联考量。我拷贝了一份github的快照,有兴趣的同学可以读读看,这是我职业生涯中遭遇的第二处runtime lib bug,至少在2019年已经有人报告,它居然还没有正式修复(截止2024/5/15)。。。 

然后,更奇妙的是使用python的monkey patch,用户可以自行封堵住这个bug。下面是github讨论中提到的补丁:

# 使用monkeypatch给python代码打补丁:
# 解决python程序在退出时自动销毁关联的sharedmemory的bug.
# 只需要在你的python应用程序启动时,调用:patch_ban_shm_tracing()就可以封堵住这个bug.
#
# 相关原始信息:
#     https://github.com/python/cpython/issues/82300

from multiprocessing import resource_tracker
 
def fix_register(name, rtype):
    if rtype == "shared_memory":
        return
    return resource_tracker._resource_tracker.register(self, name, rtype)
 
def fix_unregister(name, rtype):
    if rtype == "shared_memory":
        return
    return resource_tracker._resource_tracker.unregister(self, name, rtype)
 
def patch_ban_shm_tracing():
    resource_tracker.register = fix_register
    resource_tracker.unregister = fix_unregister
    if "shared_memory" in resource_tracker._CLEANUP_FUNCS:
        del resource_tracker._CLEANUP_FUNCS["shared_memory"]
 

这是一个很好的切入点,大家可以看看python语言本身的维护策略。开源环境,似乎类似的问题我们可以看到很多,比如:

上面是cJson.c的一处原生注释...对技术领域的文艺青年, 探查这些注释,帖子,比对开源源代码间的差异,发掘相关的故事,其实是很好的素材。

技术问题的暴露和最终的解决,所涉及的权衡,对大多数人来说,也是足够好的经验习得来源。它们可以向我们展示正确的设计该是什么样的。

created at May15,2024(zz)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子正

thanks, bro...

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值