正在阅读A lock protects an invariant, not a variable.
香港天气加载中…
QWeather ↗
← Back to the notebook

A lock protects an invariant, not a variable.

Think about the state that must stay consistent, then make the whole read–check–write operation participate in the same protocol.

Name the rule that must hold

Suppose a worker pool tracks its available slots. The useful rule is that a worker can claim a slot only when one is available. Checking the count and decrementing it are two parts of one logical operation.

If callers use different locks, or bypass the lock, they do not participate in the same synchronization protocol.

Keep the operation together

For threads sharing this in-process state, a single threading.Lock can guard both the check and the update. This snippet illustrates slot accounting; it is not a complete task scheduler.

Python
from threading import Lock

slots = 2
slots_lock = Lock()

def claim_slot():
    global slots
    with slots_lock:
        if slots == 0:
            return False
        slots -= 1
        return True

def release_slot():
    global slots
    with slots_lock:
        slots += 1

Match the primitive to the participants

Every successful claim must have exactly one release. Keep longer-running work outside the critical section when possible and use try/finally around that work to ensure release on exceptions.

A thread lock in one process does not coordinate separate processes. Async tasks also need primitives appropriate to their runtime: Python documents that asyncio synchronization primitives are not thread-safe.

Start from who shares the state, what consistency rule must hold, and which operations can interleave. Those answers determine the synchronization boundary.

References: Python thread locks ↗ · Asyncio synchronization primitives ↗

PythonConcurrencySynchronization

This is an initial starter note, ready to expand with your own examples and experience.

MORE IN DEVELOPMENT理解递归:从函数调用到逐层返回