可以通过参考计数释放Objet之前Python代垃圾收集器启动

发布于 2025-01-22 22:58:25 字数 767 浏览 2 评论 0原文

在CPYTHON多线程环境中,请考虑以下代码

class Container:
    def __del__(self):
        # Some code that fails when run in a different thread than the thread that initialized this

def use_container():
    c = Container()
    # Some code

def thread():
    use_container()

我们在其自己的线程中运行函数thread。在正常情况下,当我们调用use_container及其返回时,由于C的参考计数将降至零,因此调用其__ del __ __ del __方法。对于我正在进行的项目,我怀疑有时未调用__ del __方法,或者由其他线程调用。

我知道我们不应该依靠__ del __被调用。但是在Cpython下,当我们确定没有参考周期时,当对象参考计数达到0时__ del __ __ del __可能不会调用?

我正在考虑的一种情况是,在use_container返回之后,在解释器释放对象之前,在另一个线程中踢垃圾收集器,进而将垃圾收集器释放出来并调用其__ del__在另一个线程中的方法。有可能吗?如果是这样,一旦原始线程恢复执行会发生什么?

In a CPython multithreaded environment, consider the following code

class Container:
    def __del__(self):
        # Some code that fails when run in a different thread than the thread that initialized this

def use_container():
    c = Container()
    # Some code

def thread():
    use_container()

We are running the function thread in its own thread. Under normal circumstances, when we call use_container and it returns, as the reference count for c will drop to zero, its __del__ method is called. For a project I am working on, I suspect sometimes the __del__ method is not called, or called by a different thread.

I know we should not rely on __del__ being called. But under CPython, and when we are sure there are no reference cycles, are there any cases where __del__ might not be called when the objects reference count gets to 0?

One possible case I'm considering is, right after use_container returns, garbage collector is kicked in in another thread before the interpreter releases the object, in turn garbage collector releases the object and calls its __del__ method in another thread. Is such a case possible? And if so, what would happen in the original thread once it resumes execution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

轻拂→两袖风尘 2025-01-29 22:58:25

垃圾收集器在主线程上运行。不是孩子线。因此,1个线程无法具有参考,并且不同的线程会使对象脱颖而出。由于在解释器级别上,它仍然具有1个ref计数。

可能发生的是该对象被移至收集器中的另一代。

假设您对对象有参考。该对象被放入0。收集器可以运行但不能收集该对象,因为该对象仍在某个地方引用。如果它确实在收藏中幸存下来,它将转移到第一代,该一代的收集频率较低。如果它在第二轮中幸存下来,它将转移到第2代,在那里收集到最少的经常收集。

换句话说,根据收集器何时运行,对象可能在记忆中可以生存一段时间,而Ref计数为0,因为该对象生存在上一代中。它将一直保持内存,直到收集该一代为止,只有这样,它的__ del __才会被调用。在此处进一步阅读有关世代的进一步阅读: https://devguide.python.org/garbage_collector-garbage_collector/garbage_collector/世代

The garbage collector runs on the main thread. Not the child threads. So there is no way that 1 thread will have a reference and a different thread will del the object. Since on the interpreter level it still has a ref count of 1.

What could happen is the object is moved to a different generation within the collector.

Say you have a reference to an object. that object gets put in generation 0. The collector can run but not collect the object since it is still referenced somewhere. If it does survive collection it gets moved to generation 1 which will be collected less often. If it survives the second round of collection it will move to generation 2 where it will be collected least often.

In other words, Depending on when the collector runs the object might well survive in memory for a while with a ref count of 0 because that object lives in the last generation. It will stay in memory until that generation is collected and only then its __del__ will be called. Further reading about generations here: https://devguide.python.org/garbage_collector/#optimization-generations

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文