Overview
Atomics, channels, locks, and barriers for threads.
Every type here is a thin handle over a number. A handle carries nothing
but a registry id, so passing a handle between threads shares the same
underlying cell, queue, or lock, and two handles built from the same id
always name the same object. The registries are separate per type: an
AtomicInt and a Mutex that both use id 5 are unrelated objects.
That sharing rule is the whole design. A handle created in one thread with
byId(5) reaches the same object as a handle created in another thread
with byId(5), without any registration step, because both look the id up
in one process-wide table. Pick ids that no other code in the program uses.
Values start at their zero state the first time an id is touched, and the entry then lives for the rest of the run. There is no way to unregister an id, so reuse an id only when you mean to reopen the same object.
Blocking calls park the calling thread until the condition is met.
Channel.recv, Mutex.lock, RwLock.readLock, RwLock.writeLock,
Condvar.wait, Barrier.wait, and Thread.join all block. Each has a
non-blocking or bounded partner where one makes sense, and a
non-blocking call reports absence in its return value rather than by
throwing, so polling loops stay easy to write.
Locks are not reentrant and not owned. A lock does not track which thread
holds it, so unlocking a lock you do not hold aborts the program instead of
returning an error. Thread.join is the one call here that reports failure
as a value.
import { AtomicInt, Channel } from "@std/sync";
let counter = AtomicInt.byId(1);
counter.set(0);
let jobs = Channel.byId(2);
jobs.send("first");
jobs.send("second");
print(counter.fetchAdd(5), counter.get());
print("queued:", jobs.len(), "took:", jobs.tryRecv());When to use it
Reach for @std/sync whenever threads share anything. Every primitive is constructed byId so separate threads open the same cell — the only legal cross-thread sharing path in the language.
Capabilities
- AtomicInt counters
- Mutex/RwLock guards
- Channel/Barrier coordination
Symbols
- class AtomicInt — A 64-bit integer cell shared through the registry, with atomic access.
- class Barrier — Rendezvous gate: all count parties block in
waituntil the count-th - class Channel — An unbounded first-in-first-out queue shared through the registry.
- class Condvar — Condition variable for wait/notify coordination, shared through the
- class Mutex — Mutual exclusion lock shared through the registry.
- class RwLock — Reader-writer lock shared through the registry.
- class Thread — Owned handle to a spawned thread.
Thread.spawnreturns this nominal