The async module
Threads and concurrency, modeled on Rust’s std::thread and C++
std::thread, and tasks: green threads that take turns on a few worker
threads.
Like io, async is a module: bring it in with import async (and write
async.Thread, async.logical_cpus()) or import names directly with
import [Thread, ThreadLocal] from async.
- Atomic:
Atomic<T>, a value threads read and update without a lock - Thread: starting, naming and joining threads,
ThreadIdandThreadBody - ThreadLocal: a variable with a separate value on every thread, and its
ThreadLocalGuard<T> - Processor counts:
logical_cpus()andphysical_cpus() - Channel:
Channel<T>, a queue that carries values between threads, and itsChannelIterator<T> - Mutex:
Mutex<T>, theMutexGuard<T>awithblock holds, andCondition<T> - Once:
Once, which runs a function once, andLazy<T>, a value built on first use - Tasks:
run,Task<T>,spawn,spawn_on_each_worker,run_blocking,sleep,yield_now,timeoutand cancellation, for many tasks taking turns on a few worker threads and parking on sockets - TaskLocal: a variable with a separate value in every task, and its
TaskLocalGuard<T> - I/O backends:
Backend, how a runtime waits for sockets
Only thread-safe values can be shared between threads: numbers, shared
function values (such as a thread’s body), and [Shared] structs such as
Atomic<T>, Thread, ThreadLocal<T>, Channel<T> and Mutex<T>. Any
other value crosses threads only as a new value that nothing else
references (Channel.send(move(x)), or send(copy(x))), or stays inside
a Mutex, whose with blocks the compiler keeps apart from the rest of
the program. Lazy<T> holds thread-safe
values only. See the language guide’s Threads chapter.
Example
import async;
const hits = async.Atomic<long>(0);
work() {
hits.fetch_add(1);
}
main(): int {
var workers = Array<async.Thread>();
var n = async.logical_cpus();
var i: ulong = 0;
while (i < n) {
workers.append(async.Thread.spawn(work));
i = i + 1;
}
for (var worker in workers) {
worker.join();
}
assert(hits.load() == n as long, "every worker ran");
return 0;
}
Source: runtime/async/module.pep