The tour, 10 of 11
Threads and coroutines
Spawn and Parallel For on every core, Async and Await on one thread, and the checks that keep them safe.
FutureBlitz has two kinds of “at the same time”: threads, which run on every core, for work that takes time; and coroutines, which take turns on the main thread, for things that wait.
Spawn and Task
Spawn runs a Function on the worker pool, one thread per core, and gives a Task; Wait()
gives its result, waiting for it if it isn’t done.
Import std.core
Function SumTo(n: Int): Long
Local total: Long = 0
For i = 1 To n
total += i
End For
Return total
End Function
Local a = Spawn(Function() => SumTo(1_000_000))
Local b = Spawn(Function() => SumTo(2_000_000))
Print(a.Wait() + b.Wait())2500001500000
Parallel For
A Parallel For splits its iterations over the pool. Each one has to stand alone, as each
writing only its own element does.
Import std.core
Local squares: Long[] = []
For i = 0 Until 1000
squares.Add(0)
End For
Parallel For i = 0 Until 1000
squares[i] = (i As Long) * i
End For
Print(squares[999])998001
The compiler checks what threads share
What another thread’s work uses has to be Sendable: numbers, Strings, Structs of them, and
Shared Classes, whose Fields are ReadOnly, Atomic, or behind a Mutex. Handing an ordinary
Class to another thread, or a Local that could change while it runs, is a compile error, so a
data race doesn’t build.
Import std.core
Shared Class Stats
Field hits: Atomic<Int>
End Class
Const stats = Stats()
Parallel For i = 0 Until 100
stats.hits.Add(1)
End For
Print(stats.hits.Load())100
Coroutines
An Async Function can Await a Task without blocking its thread: it gives the thread back,
and goes on where it was when the Task is done. With std.time’s Wait, a sequence that takes
seconds is written as the steps it is.
Import std.core
Import std.time
Async Function Countdown(name: String, from: Int)
For i = from To 1 Step -1
Print("{name}: {i}")
Await Wait(100.Milliseconds)
End For
Print("{name}: go")
End Function
Countdown("race", 3)
Print("the countdown runs while the main code goes on")race: 3 the countdown runs while the main code goes on race: 2 race: 1 race: go
The program waits for its coroutines once its top-level code ends. In a game, the frame loop’s
Flip() resumes them each frame. Next: modules and packages.
Report an issue with this page or with FutureBlitz on GitHub.