mirror of
https://codeberg.org/ziglings/exercises.git
synced 2026-06-08 07:50:00 +00:00
Insert space for additional async exercises
This commit is contained in:
@@ -42,7 +42,7 @@ pub fn main(init: std.process.Init) !void {
|
||||
|
||||
try group.await(io);
|
||||
|
||||
print("Counter: {} (expected: 400)\n", .{state.counter});
|
||||
print("Counter: {}\n", .{state.counter});
|
||||
}
|
||||
|
||||
fn increment(io: std.Io, state: *SharedState, times: u32) void {
|
||||
|
||||
@@ -1,35 +1,62 @@
|
||||
//
|
||||
// You have doubtless noticed that 'suspend' requires a block
|
||||
// expression like so:
|
||||
// Tasks often need to communicate! Io provides Queue for this —
|
||||
// a bounded, thread-safe channel for passing data between tasks:
|
||||
//
|
||||
// suspend {}
|
||||
// var backing: [16]u32 = undefined;
|
||||
// var queue: std.Io.Queue(u32) = .init(&backing);
|
||||
//
|
||||
// The suspend block executes when a function suspends. To get
|
||||
// sense for when this happens, please make the following
|
||||
// program print the string
|
||||
// // Producer task:
|
||||
// try queue.putOne(io, value); // blocks if queue is full
|
||||
//
|
||||
// "ABCDEF"
|
||||
// // Consumer task:
|
||||
// const val = try queue.getOne(io); // blocks if queue is empty
|
||||
//
|
||||
const print = @import("std").debug.print;
|
||||
// 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() void {
|
||||
print("A", .{});
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
const io = init.io;
|
||||
|
||||
var frame = async suspendable();
|
||||
var backing: [4]u32 = undefined;
|
||||
var queue: std.Io.Queue(u32) = .init(&backing);
|
||||
|
||||
print("X", .{});
|
||||
var group: std.Io.Group = .init;
|
||||
|
||||
resume frame;
|
||||
group.async(io, producer, .{ io, &queue });
|
||||
group.async(io, consumer, .{ io, &queue });
|
||||
|
||||
print("F", .{});
|
||||
try group.await(io);
|
||||
}
|
||||
|
||||
fn suspendable() void {
|
||||
print("X", .{});
|
||||
|
||||
suspend {
|
||||
print("X", .{});
|
||||
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;
|
||||
}
|
||||
|
||||
print("X", .{});
|
||||
// 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});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user