Skip to content

Archive

Synchronization

10 articles
Linux 21 Sep 2026 4 min read

futex_waitv Blocks on Multiple Futex Words in One Wait

A traditional futex wait names one futex word. That maps cleanly to a mutex or condition whose blocking state is represented by one shared 32-bit value. Some synchronization designs instead need a thread to sleep until any member of several independent states changes. futex_waitv() provides that vector wait. The caller supplies an array of wait descriptors, each containing a futex address and an expected value. The kernel checks the vector and blocks only while every entry still matches its expected state.

Software Engineering 19 Sep 2026 7 min read

Sequence Counters Detect Concurrent Writes Without Reader Locks

A sequence counter can let readers copy shared state without taking the writer’s lock. The reader samples a counter, copies the protected fields, then samples the counter again. A stable even value at both observations indicates that no writer overlapped the copy under the synchronization contract. A changed or odd value forces the reader to discard the snapshot and retry. This pattern moves work away from reader-side lock ownership, but it does not remove synchronization. Writers still need serialization, counter transitions need defined memory-ordering semantics, and the protected data must remain safe to access during an overlapping write. Those constraints make sequence counters suitable for some read-mostly snapshots and unsafe for data whose lifetime can disappear beneath a reader.

Software Engineering 19 Sep 2026 6 min read

Fencing Tokens Reject Stale Writers After Lease Expiry

A distributed lease can transfer ownership without stopping the process that previously held it. A worker may pause long enough for its lease to expire, then resume after another worker has acquired the same lease. At that point both processes can execute code that was written under the assumption of exclusive ownership. Lease expiry settles ownership in the coordination service. It does not revoke CPU time, cancel an in-flight network request, or erase buffered I/O on the former holder. Fencing tokens address that gap by carrying an ordering value from the ownership decision to the resource being protected.

Software Engineering 19 Sep 2026 6 min read

Fencing Tokens Close the Stale Lease Writer Gap

A distributed lease can expire while its holder is unable to run. The holder may later resume with local state that still says it owns the lease, even though another client has already acquired a newer lease. If the protected storage or service accepts operations solely because the client once acquired the lease, two clients can mutate the same resource across different points in time. A fencing token moves the decisive check from lease ownership into the protected resource. Each successful acquisition receives a token ordered after every earlier token. The resource records the greatest accepted token and rejects operations carrying an older value. The lease still coordinates acquisition, but the token constrains what a delayed former holder can do after it resumes.

Go 16 Sep 2026 5 min read

Go WaitGroup Reuse Requires Completed Wait Boundaries

A sync.WaitGroup can be reused after a wait phase completes, but a new independent task set cannot begin while calls to Wait from the prior phase are still active. The boundary is the return of every earlier Wait, not merely the instant at which the internal task counter reaches zero. This constraint matters when one WaitGroup instance is retained across batches, epochs, request waves, or repeated coordination cycles. Reuse is supported, but phases must not overlap at the zero-to-positive counter transition.

Go 16 Sep 2026 4 min read

Go sync.Cond Wait Rechecks Shared State

sync.Cond.Wait resumes after a notification, but the notification does not assert that a caller-specific condition is still true when the goroutine reacquires the lock. The shared predicate remains the source of truth, so a waiter checks it again after every return from Wait. This boundary separates notification from state. Signal and Broadcast announce that relevant state may have changed; they do not transfer ownership of that state or reserve it for a particular waiter.

Software Engineering 15 Sep 2026 7 min read

Fencing Tokens Reject Stale Lock Holders

A process acquires a distributed lease, pauses long enough for that lease to expire, then resumes. Another process has already acquired the same lease. At that moment both processes can execute code that was entered under an apparently valid acquisition, even though only the newer owner should retain authority. The lease itself cannot retract instructions from the paused process. Expiration changes coordination state; it does not erase local state, stop a suspended runtime, or cancel an operation already queued elsewhere. This gap is the central limitation of treating a distributed lock as a remote version of an in-process mutex.

Go 12 Sep 2026 4 min read

Track Goroutine Lifetimes with sync.WaitGroup.Go in Go

sync.WaitGroup.Go combines goroutine creation with task accounting. Added in Go 1.25, the method removes a small but consequential gap between incrementing a wait-group counter and starting the goroutine that will eventually decrement it. The method does not change what a WaitGroup represents. It still tracks a set of tasks and lets another goroutine block until that set is complete. The difference is that registration and goroutine launch now share one operation.

Go 12 Sep 2026 5 min read

Cache Concurrent Initialization Results with sync.OnceValue in Go

sync.OnceValue turns a function into a concurrency-safe, one-time computation whose result is returned on every call. The first caller performs the computation. Concurrent callers wait for that call to finish, and later callers receive the stored result without running the function again. This differs from using sync.Once with a separate result variable. The value and its one-time initialization are packaged behind a function, which makes the lifetime of the cached result explicit in the place where that function is stored.

Go 04 Sep 2026 10 min read

Coordinate Shared State with sync.Cond in Go

A goroutine sometimes cannot make progress until shared state changes. A worker may need to wait until a queue contains an item. A producer may need to wait until that queue has free capacity. Several goroutines may need to sleep until a service becomes ready. Polling the state in a loop wastes CPU or forces you to invent arbitrary sleep intervals. Channels solve many coordination problems more directly, but they are not always a natural fit when several goroutines already share state protected by a mutex and need to wait for predicates over that state.