diff options
| author | Chris Boesch <chrboesch@noreply.codeberg.org> | 2026-04-03 18:11:00 +0200 |
|---|---|---|
| committer | Chris Boesch <chrboesch@noreply.codeberg.org> | 2026-04-03 18:11:00 +0200 |
| commit | 1c6487c1e79cbe0d59a39b483af8ec44b59c586e (patch) | |
| tree | 22f774d62d15252e17db75b22be40d7606fe606f /exercises/092_async8.zig | |
| parent | 25009361533be5e45cf59d9840edf5d13cfb8d6d (diff) | |
added async-io quiz
Diffstat (limited to 'exercises/092_async8.zig')
| -rw-r--r-- | exercises/092_async8.zig | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/exercises/092_async8.zig b/exercises/092_async8.zig new file mode 100644 index 0000000..10921c3 --- /dev/null +++ b/exercises/092_async8.zig @@ -0,0 +1,62 @@ +// +// Tasks often need to communicate! Io provides Queue for this — +// a bounded, thread-safe channel for passing data between tasks: +// +// var backing: [16]u32 = undefined; +// var queue: std.Io.Queue(u32) = .init(&backing); +// +// // Producer task: +// try queue.putOne(io, value); // blocks if queue is full +// +// // Consumer task: +// const val = try queue.getOne(io); // blocks if queue is empty +// +// When the producer is done, it calls queue.close(io) to signal +// that no more data is coming. After that, getOne() will return +// error.Closed once the queue is drained. +// +// This is the classic producer/consumer pattern — one task +// generates work, another processes it, and the queue handles +// all the synchronization automatically. +// +// Fix this program: the producer sends numbers 1..10, the +// consumer sums them up. The expected sum is 55. +// +const std = @import("std"); +const print = std.debug.print; + +pub fn main(init: std.process.Init) !void { + const io = init.io; + + var backing: [4]u32 = undefined; + var queue: std.Io.Queue(u32) = .init(&backing); + + var group: std.Io.Group = .init; + + group.async(io, producer, .{ io, &queue }); + group.async(io, consumer, .{ io, &queue }); + + try group.await(io); +} + +fn producer(io: std.Io, queue: *std.Io.Queue(u32)) void { + // Send numbers 1 through 10 into the queue. + for (1..11) |i| { + // What Queue method sends a single element, blocking if full? + queue.???(io, @intCast(i)) catch return; + } + // Signal that we're done sending. + queue.close(io); +} + +fn consumer(io: std.Io, queue: *std.Io.Queue(u32)) void { + var sum: u32 = 0; + while (true) { + const value = queue.getOne(io) catch |err| switch (err) { + error.Closed => break, + error.Canceled => return, + }; + sum += value; + } + print("Sum of 1..10 = {}\n", .{sum}); +} |
