|
//! A semaphore is an unsigned integer that blocks the kernel thread if //! the number would become negative. //! This API supports static initialization and does not require deinitialization. |
wait()It is OK to initialize this field to any value. |
mutex: Mutex = .{}, cond: Condition = .{}, /// It is OK to initialize this field to any value. permits: usize = 0, |
post() |
const Semaphore = @This(); const std = @import("../std.zig"); const Mutex = std.Thread.Mutex; const Condition = std.Thread.Condition; const builtin = @import("builtin"); const testing = std.testing; |
Test:Thread.Semaphore |
pub fn wait(sem: *Semaphore) void { sem.mutex.lock(); defer sem.mutex.unlock(); while (sem.permits == 0) sem.cond.wait(&sem.mutex); sem.permits -= 1; if (sem.permits > 0) sem.cond.signal(); } pub fn post(sem: *Semaphore) void { sem.mutex.lock(); defer sem.mutex.unlock(); sem.permits += 1; sem.cond.signal(); } test "Thread.Semaphore" { if (builtin.single_threaded) { return error.SkipZigTest; } const TestContext = struct { sem: *Semaphore, n: *i32, fn worker(ctx: *@This()) void { ctx.sem.wait(); ctx.n.* += 1; ctx.sem.post(); } }; const num_threads = 3; var sem = Semaphore{ .permits = 1 }; var threads: [num_threads]std.Thread = undefined; var n: i32 = 0; var ctx = TestContext{ .sem = &sem, .n = &n }; for (&threads) |*t| t.* = try std.Thread.spawn(.{}, TestContext.worker, .{&ctx}); for (threads) |t| t.join(); sem.wait(); try testing.expect(n == num_threads); } |
Generated by zstd-live on 2025-08-12 12:37:59 UTC. |