thread
Use thread to run functions in the background, coordinate parallel work, and pass messages.
import "std:thread"Example
import "std:thread"
auto t = thread.new(def() -> ( return 42 ))
log t.wait()API reference
thread
thread.new(fn: any, ...args: any)
*Thread
Creates and starts a new thread.
thread.wait()
any
Waits for the result. If the task failed, rethrows its error with the original task and spawn locations.
thread.timeout(ms: number)
any
Waits up to ms milliseconds for the result; returns the result if the task finished in time, otherwise null. If a completed task failed, rethrows its error. A timeout stops waiting; it does not cancel the task.
thread.isDone()
boolean
thread.age()
number
Returns the age of the thread in milliseconds.
thread.waitAll(threads: array)
array
Waits for every thread and preserves null positions for non-thread entries. If tasks fail, waits for the rest before rethrowing the first error with additional failures attached.
thread.race(threads: array)
any
Waits for the first thread in the array to complete and returns its result. If the winning task failed, rethrows its error.
thread.parallel(items: array, fn: any, limit?: number)
array
Runs fn(item, index) across items in parallel with an optional worker concurrency limit, returning results in input index order.
thread.channel(capacity?: number)
*Channel
Creates a thread-safe message channel with optional buffer capacity.
*Channel
channel.send(value: any)
boolean
Sends a value into the channel. Returns false if closed, otherwise true.
channel.recv()
any
Receives a value from the channel, blocking until an item is available or the channel is closed. Returns null when closed and empty.
channel.tryRecv()
any
Non-blocking receive. Returns the next item or null if empty or closed.
channel.close()
void
Closes the channel.
channel.isClosed()
boolean
channel.len()
number
Returns the number of buffered items currently in the channel.
Thread safety
OSL automatically makes concurrent programs memory-safe. The compiler identifies named functions that can run as scoped threads, including their transitive calls, and guards concurrent operations with shared read/write statement and collection locks. Dynamic callbacks use a safe whole-program fallback. This means:
Two threads touching the same object, array,
map(), orset()will never crash the program or corrupt memory.Every OSL statement is atomic, including an index write,
.append,.set, key read, or scalar read-modify-write such ascount += 1.
Automatic safety does not combine multiple statements into one transaction. For example, another thread can change count between an if count < limit check and the assignment inside its block. Guard multi-statement critical sections with osl/sync.
Performance: programs that never start a thread skip capture analysis and pay nothing; the locking is compiled out entirely. Named thread functions use a constant-time function-only scope lookup without reading their captured globals during thread creation. Generic, typed, read, and write array operations share the same lock path, and read-only statements can run in parallel. Shared scalar reads in polling conditions and pure conversions use that read boundary as well. Mutable statements use a shared statement boundary so scalar and collection updates remain atomic. Method and package calls use their own value/package synchronization and run outside that boundary, allowing HTTP, WebSocket, and similar callbacks to update captured values without deadlocking their caller.
Automatic collection locking uses a single world lock, so growing or replacing an array's backing storage needs no lock-identity propagation and cyclic values need no recursive registration. Explicit locks from osl/sync are still your responsibility: always release them and use a consistent order when acquiring more than one.
Notes
Prefer
import "std:thread"; the olderimport "osl/thread"spelling remains supported.defer <statement>runs a statement when the enclosing function returns (like Go'sdefer), which is handy for releasing anosl/synclock taken inside a thread.Panicking tasks still complete their handle.
waitand a completedtimeoutrethrow the failure;waitAllwaits for every task before rethrowing.
Last updated