Channels
Channels provide message passing between tasks.
Basic Usage
wyn
ch = Task.channel(10) // buffered channel, capacity 10
Task.send(ch, 42)
Task.send(ch, 100)
first = Task.recv(ch) // 42
second = Task.recv(ch) // 100Producer / Consumer
wyn
fn producer(ch: int, n: int) -> int {
for i in 0..n {
Task.send(ch, i * i)
}
return 0
}
fn main() -> int {
ch = Task.channel(100)
f = spawn producer(ch, 10)
for i in 0..10 {
print(Task.recv(ch).to_string())
}
await f
return 0
}Messages are received in FIFO order.
Select (Multiple Channels)
Wait on multiple channels simultaneously using Task.select_2 or Task.select_3. Returns the 0-based index of the first channel with data.
wyn
fn sender(ch: int, value: int, delay_ms: int) {
Time.sleep(delay_ms)
Task.send(ch, value)
}
ch1 = Task.channel(8)
ch2 = Task.channel(8)
// In another coroutine, someone sends to ch2
spawn sender(ch2, 42, 100)
// Wait for either channel
ready = Task.select_2(ch1, ch2)
if ready == 0 {
val = Task.recv(ch1)
print("got from ch1: " + val.to_string())
} else if ready == 1 {
val = Task.recv(ch2)
print("got from ch2: " + val.to_string())
}Task.select_2(ch1, ch2)- wait on 2 channelsTask.select_3(ch1, ch2, ch3)- wait on 3 channels- Returns
-1if all channels are closed - Inside a coroutine,
selectyields instead of blocking
Draining Until Closed
When you don't know how many messages will arrive, close the channel from the producer and drain it with select. Task.select_2 returns -1 once every channel it watches is closed and empty, which gives the consumer a clean exit:
wyn
fn producer(ch: int) -> int {
for i in 0..5 {
Task.send(ch, i * 10)
}
Task.close(ch)
return 0
}
fn main() -> int {
ch = Task.channel(8)
spawn producer(ch)
while true {
ready = Task.select_2(ch, ch) // -1 when ch is closed and drained
if ready == -1 { break }
print(Task.recv(ch).to_string())
}
return 0
}Note: a receive on a drained channel returns
0, which is indistinguishable from a sent0. Prefer reading a known count of messages, or draining withselectas above, rather than looping on the received value.
See Also
- Spawn & Await - create concurrent tasks
- Generators - yield-based alternatives