Threads in Zig

This Zig program is a short demonstration of multithreading with the standard library. It starts by importing the standard library with const std = @import("std");.

const std = @import("std");

fn threadFunc(arg: usize) void {
    std.debug.print("Hello from thread! Arg = {}\n", .{arg});
}

pub fn main(init: std.process.Init) !void {
    _ = init;
    const thr1 = try std.Thread.spawn(.{}, threadFunc, .{1234});
    std.debug.print("Hello from main thread!\n", .{});
    const thr2 = try std.Thread.spawn(.{}, threadFunc, .{4321});

    thr1.join();
    thr2.join();

    std.debug.print("All threads have finished.\n", .{});
}

A simple worker function named threadFunc() is defined to take a single usize argument and print a message that includes that value. As expected, the entry point of the program is main(), which receives a std.process.Init value (immediately discarded) and returns an error-union !void.

Inside main() two threads are launched with std.Thread.spawn(). The first call creates a thread that runs threadFunc() with the argument 1234; the second call does the same with the argument 4321. Between the two spawn statements the main thread itself prints a greeting, so its output appears interleaved with the messages coming from the worker threads.

After both threads have been started, main() waits for them to finish by calling join() on each thread handle. Only when both joins have returned does the program print a final confirmation that every thread has completed. The overall effect is a concise illustration of concurrent execution, argument passing to threads, and proper synchronization before program termination.

Save the code as threads.zig and execute it as follows:

$ zig run threads.zig
Hello from main thread!
Hello from thread! Arg = 1234
Hello from thread! Arg = 4321
All threads have finished.

Want to learn more about Zig, look at my book Systems Programming with Zig.

Happy coding in Zig!