Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python free-threaded builds: lock the whole shared-state update

Last updated: 1 Oct 20265 min read
tutorial
IntermediateBy AITrove Editorial

An optional free-threaded CPython build changes scheduling; a shared application invariant still needs an explicit lock.

Download Python source kit

Operation contract

Four workers each record forty-seven accepted events. The count is updated inside one lock, so the final count is 188 regardless of scheduling. The program also reads the running process's GIL state instead of guessing from its Python version. The displayed state is from the checked standard build.

Failure boundary

The GIL state can differ on a free-threaded binary and can change when an extension enables it. A successful run under the usual build is not a concurrency stress test. Every writer and reader of a multi-field invariant must follow the same synchronization policy; a thread-safe dictionary operation alone cannot make a larger transaction atomic.

Working program

python
import sys
from threading import Lock, Thread

accepted_events = 0
event_lock = Lock()

def record_events():
    global accepted_events
    for _ in range(47):
        with event_lock:
            accepted_events += 1

workers = [Thread(target=record_events) for _ in range(4)]
for worker in workers:
    worker.start()
for worker in workers:
    worker.join()
print("gil_enabled", sys._is_gil_enabled())
print("accepted", accepted_events)

Output

Output
gil_enabled True
accepted 188

Costs and limits

The four workers perform 188 locked increments. Lock contention can serialize this short operation; measure a real workload on each supported interpreter build.

Common Mistakes

  • A free-threaded build is not proof that a compound operation is safe without a lock.
  • The version number does not reveal the process's current GIL state.
  • Do not infer a speedup from a tiny counter fixture.

Connected lessons

Test this contract.

Continue with Python free-threaded diagnostics: separate build capability from current GIL state.

python
free-threaded-lock-contract
Storage details