Skip to main content

Lib/threading.py

Source:

cpython 3.14 @ ab2d84fe1023/Lib/threading.py

Map

LinesSymbolNotes
1–90module prologue, importsimports _thread, _threading_local, time, os
91–180Lock, RLockthin wrappers around _thread.allocate_lock and _thread.RLock
181–340Conditionwait/notify/notify_all built on an underlying lock
341–440Semaphore, BoundedSemaphorecounter guarded by a Condition
441–510Eventboolean flag, wait delegates to an internal Condition
511–640Barriern-party rendezvous; phases: filling, draining, resetting, broken
641–960Threadstart, run, _bootstrap, _bootstrap_inner, _delete, join
961–1050_MainThread, _DummyThreadsingletons registered at import time
1051–1200localre-export of _threading_local.local; per-thread __dict__
1201–1350current_thread, main_thread, enumerate, active_countregistry helpers
1351–1500_shutdownjoin non-daemon threads at interpreter exit
1501–1600excepthook, get_ident, settrace, setprofile, mischooks and utility exports

Reading

Thread lifecycle: start, _bootstrap, _delete

Thread.start calls _thread.start_new_thread with _bootstrap as the entry point. _bootstrap sets up exception handling, invokes _bootstrap_inner, and guarantees _delete runs even when an unhandled exception escapes.

# CPython: Lib/threading.py:930 Thread._bootstrap
def _bootstrap(self):
self._bootstrap_inner()

# CPython: Lib/threading.py:940 Thread._bootstrap_inner
def _bootstrap_inner(self):
try:
self._set_ident()
self._set_tstate_lock()
...
self.run()
except:
self._invoke_excepthook(self)
finally:
with _active_limbo_lock:
self._delete()

_delete removes the thread from _active and releases the _tstate_lock, allowing join callers to unblock.

Lock, RLock, and Condition

Lock and RLock are exposed as factories rather than classes; Lock() returns _thread.allocate_lock() directly. Condition wraps any lock-like object and exposes wait, notify, and notify_all.

# CPython: Lib/threading.py:265 Condition.wait
def wait(self, timeout=None):
if not self._is_owned():
raise RuntimeError("cannot wait on un-acquired lock")
waiter = _allocate_lock()
waiter.acquire()
self._waiters.append(waiter)
saved_state = self._release_save()
gotit = False
try:
if timeout is None:
waiter.acquire()
gotit = True
else:
gotit = waiter.acquire(True, timeout)
return gotit
finally:
self._acquire_restore(saved_state)
if not gotit:
try:
self._waiters.remove(waiter)
except ValueError:
pass

Barrier

Barrier implements an n-party rendezvous. Internally it tracks a _phase integer (incremented each time all parties arrive) and a _count of threads currently waiting. The phases cycle through filling, draining, and resetting states.

# CPython: Lib/threading.py:592 Barrier.wait
def wait(self, timeout=None):
with self._cond:
self._enter()
index = self._count
self._count += 1
try:
if index + 1 == self._parties:
self._release()
else:
self._wait(timeout)
return index
finally:
self._count -= 1
self._exit()

gopy notes

Status: not yet ported.

Planned package path: module/threading/.

The port requires _thread (low-level OS thread primitives) to be available first. _threading_local must also be ported so that local() can be re-exported. Daemon-thread tracking and the _shutdown hook depend on interpreter lifecycle events that will need a gopy-specific integration point.