本文由 AI 分析生成
建立時間: 2026-03-28 來源: https://kristoff.it/blog/asynchrony-is-not-concurrency/
Summary
Loris Cro (Zig core team) argues that confusing asynchrony with concurrency has caused the async/await local minima that plagues modern programming ecosystems: viral async syntax, library duplication (sync vs async versions), and deadlock-prone escape hatches. His proposed distinctions — asynchrony = tasks can run out of order and still be correct; concurrency = system can progress multiple tasks simultaneously — lead to Zig’s io.async design where async code does not imply concurrency and can run in single-threaded blocking mode.
Loris Cro 論證混淆非同步性與並發性導致了現代編程生態的 async/await 困境:病毒式傳播的 async 語法、函式庫重複(sync/async 兩套)和 escape hatch 死鎖問題。Zig 的 io.async 設計讓非同步程式碼不隱含並發性,可在單執行緒阻塞模式下運行。
Key Points
- Proposed definitions:
- Asynchrony: the possibility for tasks to run out of order and still be correct (ordering doesn’t matter for correctness)
- Concurrency: the ability to progress multiple tasks at a time (via parallelism or task switching)
- Parallelism: multiple tasks executing simultaneously at the physical level
- The missing distinction: saving two files is asynchronous (either order is correct); client-server socket connect/accept requires concurrency (both must be active simultaneously)
- Zig’s solution:
io.asyncexpresses asynchrony without implying concurrency — can run in single-threaded blocking mode;io.asyncConcurrentexplicitly requires concurrency and is failable - Why it matters: libraries written with
io.asynccan be used from both sync and async callers without duplication; no viral async propagation - Go parallel: Go solves the same problem differently — all I/O is evented, goroutines can task-switch, but surface code looks synchronous
Insights
The article identifies the root cause of “async color” (the problem where async functions can only call other async functions, forcing async to propagate virally): it conflates asynchrony (property of task ordering) with concurrency (mechanism for progress). Once you separate these, you can have a single codebase that works under any execution model — blocking, evented, threaded.
The redis-py vs. asyncio-redis duplication example illustrates the real cost: library authors must choose their “color” at design time, and users are locked in. Zig’s model removes this choice — io.async is a statement about ordering requirements, not execution mechanism.
asyncConcurrent being failable (it returns an error if concurrency can’t be provided) makes concurrency requirements explicit and verifiable at runtime — a property most async systems don’t have. You can test your code in single-threaded mode and know exactly which operations require true concurrency.
Connections
Raw Excerpt
Asynchrony: the possibility for tasks to run out of order and still be correct. Concurrency: the ability of a system to progress multiple tasks at a time. Because of our lack of understanding, we have created language ecosystems where library authors must duplicate effort, where async code is viral, and where even a single async dependency forces users to abandon synchronous code.