xxc

可编译可解释的系统级语言 - 确定性 ARC 无 GC / 全自举工具链 / 三后端逐字节一致

📂 开发工具#编程语言#编译器#自举#跨平台#无GC#并发#开发工具📅 2026-10-9

Concurrency Guide

📅 2026-10-9

xxc Concurrency Guide

> Requires the --features concurrency build (all official binaries ship

> with it). The interpreter and compiled binaries carry the same

> worker-pool runtime with identical semantics. Related pages:

> Language Guide ·

> Quick Start ·

> 中文版:并发编程指南。

Concurrency

*(Requires --features concurrency. Available in the interpreter AND in

compiled binaries — compiled programs carry the same worker-pool runtime.)*

spawn starts a task that runs in parallel on the runtime's worker

threads (XXC_CONC_WORKERS, default derived from the CPU count). Tasks are

cheap (each is a coroutine with its own stack) — spawn thousands.

ch := chan(4)               // buffered channel (capacity 4)
spawn {
    ch <- compute()         // send
}
v := <-ch                   // receive (blocks until available)
  • chan() creates an unbuffered (rendezvous) channel; chan(n) a

buffered one.

  • Sends block while full; receives block while empty; both park the task

(other tasks keep running).

  • A value sent on an unbuffered channel transfers directly to a waiting

receiver.

select

select {
    case x := <-ch1 { print("ch1:", x) }
    case ch2 <- 42   { print("sent") }
    default          { print("nothing ready") }   // optional: non-blocking
}

select commits to whichever operation is ready; with default it never

blocks. Channels and send-values are evaluated once, on entry.

Semantics

  • main returns → program exits (remaining tasks are dropped), matching Go.
  • If every task is blocked with no pending I/O, the runtime reports a

deadlock with source position.

  • Tasks may share class instances, arrays, and channels; struct values

are copied between tasks.

// parallel fan-out
results := chan(4)
for i in range(0, 4) {
    spawn { results <- fib(31) }
}
sum := 0
for i in range(0, 4) { sum = sum + <-results }

On a 4+ core machine this runs measurably faster than the sequential

equivalent (~2.3× measured for 4 tasks).

Async I/O

*(Requires --features concurrency.)* The modules std/fs, net/tcp, and

net/http perform blocking-looking calls that never stall other tasks:

work is offloaded to an I/O thread pool and the task parks until completion.

import fs "std/fs"
import tcp "net/tcp"

content := fs.read_file("data.txt")     // yields; other tasks run
c := tcp.accept(listener)               // yields

Line-atomic printing

The parts of a print statement (strings/ints/floats) are appended to a

per-line buffer under a statement-level owner-token lock and flushed as

one write at the newline — on every backend, concurrent tasks can

never tear an output line. The property is verified word-for-word by the

stress multiset gates at w=2 and w=4:

# verification (in the repo): the sorted w=4 line multiset must equal w=1
XXC_CONC_WORKERS=4 ./stress_conc | sort   # == the sorted w=1 output

Runtime behavior quick notes

  • main returning exits the program (remaining tasks dropped), matching Go;
  • if every task is blocked with no pending I/O, the runtime reports a

deadlock with source position;

  • XXC_CONC_WORKERS=N selects the worker count (derived from the CPU

count by default);

  • tasks share class instances, arrays, and channels; struct values are

copied between tasks.