Fibers
Fiber
Fibers are user-space threads without a scheduler; a Fiber can yield and resume its execution from the place it has exited. A Fibers (or coroutine as called in other languages) are special functions that can be interrupted at any time by the user.
When a conventional function is invoked, execution begins at the start, and once a function exits, it is finished. By contrast, Fibers can exit by calling other Fibers, which may later return to the point where they were invoked in the original coroutine:
func main() {
var fiber = Fiber.create({
System.print("fiber 1");
Fiber.yield()
System.print("fiber 2");
});
System.print("main 1");
fiber.call()
System.print("main 2");
fiber.call()
System.print("main 3");
}
// Output:
// main 1
// fiber 1
// main 2
// fiber 2
// main 3
A Fiber is created with create
:
Fiber.create( {
System.print("\(self) is the current fiber")
})
and executed till the next yield
with fiber.call()
var closure = {
System.print("1")
Fiber.yield()
System.print("2")
Fiber.yield()
System.print("3")
Fiber.yield()
System.print("Done")
}
var fiber = Fiber.create(closure)
fiber.call()
// prints 1
fiber.call()
// prints 2
fiber.call()
// prints 3
fiber.call()
// prints Done
System.print(fiber.isDone())
// prints true
There are 2 types of yield:
Fiber.yield()
it returns the controll to the function callingcall()
Fiber.yieldWaitTime(seconds)
it returns the controll to the function callingcall()
and also store the current time internally.
The later enable a call check of the total time in seconds passed since last call()
. If the time amount is not enough the call is void and the fiber is not entered.
Example:
To implement a function that do some stuff every second, like a timer, a way is to use Fiber.yieldWaitTime(seconds)
var fiber = Fiber.create({
var keepGoing = true
while (keepGoing) {
keepGoing = doSomeStuff()
Console.write("Waiting")
Fiber.yieldWaitTime(1.0)
Console.write("Elapsed time: \(self.elapsedTime())")
}
})
...
// Note: this strict loop is just for reference, not a real case.
while (!fiber.isDone()) {
fiber.call()
}