summaryrefslogtreecommitdiff
path: root/exercises/093_async9.zig
blob: ad30dcffa98d99e9415534064af658053bfe1d1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//
// We've been using io.async() to launch tasks. But there's a
// stronger variant: io.concurrent().
//
// The difference:
//
//   io.async():
//     * The function MAY run on another thread, or it may run
//       immediately on the current thread (synchronously).
//     * Never fails — if no thread is available, it just runs
//       the function right away.
//     * More portable, works with all Io backends.
//
//   io.concurrent():
//     * GUARANTEES a separate unit of concurrency (a real thread
//       in the Threaded backend).
//     * Can fail with error.ConcurrencyUnavailable if resources
//       are exhausted or the backend doesn't support it.
//     * Use when you NEED true parallelism.
//
// Because concurrent() can fail, you must handle the error:
//
//     var future = try io.concurrent(myFn, .{args});
//     const result = future.await(io);
//
// Notice the 'try' — that's the key difference in usage!
//
// Fix this program to launch the computation concurrently.
//
const std = @import("std");
const print = std.debug.print;

pub fn main(init: std.process.Init) !void {
    const io = init.io;

    // Launch with a guaranteed separate thread.
    // Which Io method guarantees true concurrency?
    // (Hint: unlike io.async, this one can fail!)
    var future = try io.???(compute, .{io});

    print("Main thread continues...\n", .{});

    // Wait 100 millisecond so the output order is deterministic.
    io.sleep(std.Io.Duration.fromMilliseconds(100), .awake) catch {};

    print("Main thread done waiting.\n", .{});

    const result = future.await(io);
    print("Result: {}\n", .{result});
}

fn compute(io: std.Io) u32 {
    print("Computing on a separate thread!\n", .{});
    // Simulate some work.
    io.sleep(std.Io.Duration.fromMilliseconds(200), .awake) catch return 0;
    return 123;
}