最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

garbage collection - Why does Python 3.14 use ob_ref_local and ob_ref_shared for reference counts when GIL is absent - Stack Ove

programmeradmin3浏览0评论

According to Include/object.h in Python's source code:

struct _object {
    // ob_tid stores the thread id (or zero). It is also used by the GC and the
    // trashcan mechanism as a linked list pointer and by the GC to store the
    // computed "gc_refs" refcount.
    uintptr_t ob_tid;
    uint16_t ob_flags;
    PyMutex ob_mutex;           // per-object lock
    uint8_t ob_gc_bits;         // gc-related state
    uint32_t ob_ref_local;      // local reference count
    Py_ssize_t ob_ref_shared;   // shared (atomic) reference count
    PyTypeObject *ob_type;
};

When I managed to use an external tool, pyobject, to inspect them:

C:\Users\admin>py314t
Python 3.14.0a5 experimental free-threading build (tags/v3.14.0a5:3ae9101, Feb 11 2025, 17:44:01) [MSC v.1942 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyobject import getrefcount_nogil,setrefcount_nogil
>>> class A:pass
...
>>> a=A()
>>> getrefcount_nogil(a)
(1, 0) # the first is ob_ref_local and the second is ob_ref_shared
>>> def another_thread():
...     b=a
...     while True:pass
...
>>> from _thread import start_new_thread
>>> start_new_thread(another_thread,())
10824
>>> getrefcount_nogil(a)
(1, 5)
>>>

So, what is the function and implication of ob_ref_local and ob_ref_shared values that replace ob_refcnt?

According to Include/object.h in Python's source code:

struct _object {
    // ob_tid stores the thread id (or zero). It is also used by the GC and the
    // trashcan mechanism as a linked list pointer and by the GC to store the
    // computed "gc_refs" refcount.
    uintptr_t ob_tid;
    uint16_t ob_flags;
    PyMutex ob_mutex;           // per-object lock
    uint8_t ob_gc_bits;         // gc-related state
    uint32_t ob_ref_local;      // local reference count
    Py_ssize_t ob_ref_shared;   // shared (atomic) reference count
    PyTypeObject *ob_type;
};

When I managed to use an external tool, pyobject, to inspect them:

C:\Users\admin>py314t
Python 3.14.0a5 experimental free-threading build (tags/v3.14.0a5:3ae9101, Feb 11 2025, 17:44:01) [MSC v.1942 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyobject import getrefcount_nogil,setrefcount_nogil
>>> class A:pass
...
>>> a=A()
>>> getrefcount_nogil(a)
(1, 0) # the first is ob_ref_local and the second is ob_ref_shared
>>> def another_thread():
...     b=a
...     while True:pass
...
>>> from _thread import start_new_thread
>>> start_new_thread(another_thread,())
10824
>>> getrefcount_nogil(a)
(1, 5)
>>>

So, what is the function and implication of ob_ref_local and ob_ref_shared values that replace ob_refcnt?

Share Improve this question asked Feb 16 at 18:25 qfcyqfcy 1451 silver badge6 bronze badges New contributor qfcy is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 2
  • 2 I'm not sure that here is the right palce to ask such things. So, what is YOUR problem? – Bohdan Commented Feb 16 at 19:59
  • discuss.python. would be a better source for information about pre-release details of CPython. – chepner Commented Feb 16 at 20:19
Add a comment  | 

1 Answer 1

Reset to default 1

The documentation of new reference counting features can be found in peps.python./pep-0703/#reference-counting.

According to the PEP, in biased reference counting that assumes most objects are linked to one owning thread, the owning thread utilize non-atomic instructions to adjust the local reference count, while other threads employ atomic instructions to modify the shared reference count.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论