[Python] Why does Python 3.14 use ob_ref_local and ob_ref_shared for reference counts when GIL...

Discussão em 'Python' iniciado por Stack, Fevereiro 16, 2025.

  1. Stack

    Stack Membro Participativo

    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?

    Continue reading...

Compartilhe esta Página