While the cooperative concepts model offers an efficient model for dealing with many tasks that often are blocked on I/O, it is not suitable for long-running computations that would prevent concurrent tasks from progressing.
Multithreading offers a way to offload heavy computations to be executed in parallel with the async work, or, in cases where a single event loop gets overloaded, to manage multiple event loops in parallel.
For interaction between threads, the threadsync: ThreadSignalPtr type is used - both to wait for notifications coming from other threads and to notify other threads of progress from within an async procedure.
import chronos, chronos/threadsync import os type Context = object # Context allocated by `createShared` should contain no garbage-collected # types! signal: ThreadSignalPtr value: int proc myThread(ctx: ptr Context) {.thread.} = echo "Doing some work in a thread" sleep(3000) ctx.value = 42 echo "Done, firing the signal" discard ctx.signal.fireSync().expect("correctly initialized signal should not fail") proc main() {.async.} = let signal = ThreadSignalPtr.new().expect("free file descriptor for signal") context = createShared(Context) context.signal = signal var thread: Thread[ptr Context] echo "Starting thread" createThread(thread, myThread, context) await signal.wait() echo "Work done: ", context.value joinThread(thread) signal.close().expect("closing once works") deallocShared(context) waitFor main()