Thread Barriers

Does Zig (either the language or the standard library) have features for thread synchronization/coordination? In C, I can simply use pthread barriers (pthread_barrier_t) to make each thread wait until all threads have reached the barrier. The main thread initializes the barrier with pthread_barrier_init(), then each thread only needs to call pthread_barrier_wait(). However, I can’t find any such functionality in the Zig standard library, so I’m wondering if I will have to implement it from scratch.

If I do implement thread barriers on my own, I assume I will have to use std.Thread.Mutex and std.Thread.Condition. A variable, protected by the Mutex, keeps track of the number of threads that are waiting at the barrier. Each time a thread enters the barrier, it increments that variable by 1. If the number of threads at the barrier is not equal to the total number of threads, the thread waits for the Condition. Otherwise, it sets the number of threads waiting at the barrier to zero (reset) and broadcasts the Condition, allowing all threads to continue.

Please correct me if that draft of an implementation is flawed or if you know of a much better way.

(BTW, I feel like there should be a concurrency, parallelism or multithreading tag. I can’t figure out how to add a new tag, so I assume that I’m not allowed to do that.)

“thread join” is the term you’re looking for, when searching for info on the subject.

Have a look at std.Thread.WaitGroup and std.Thread.ResetEvent, they should be the necessary building blocks, though mutex+condition is also a possible route, depending on the situation.

@pachde join is for waiting for threads to complete.

1 Like

The documentation for std.Thread.WaitGroup is lacking explanations. Do I simply create a WaitGroup object and call reset() on it once, then call wait() in each thread? Can this be used over many loop iterations, or do I need to somehow reset the WaitGroup after every iteration?

Yeah Zig is under heavy development and a lot of things will lack documentation for the time being.

One thing I recommend is having the Zig source code locally, so you can quickly navigate to relevant tests and implementations. In general, the std lib is very readable.

For example, if you need a simple barrier, maybe the approach in the broadcast test is all you need? As for WaitGroup, the implementation is very short.

Pool.zig and hasher.zig are other usage examples in the Zig source.

If WaitGroup and simple ResetEvent barriers isn’t enough for your use case, there are also many examples of Thread.Condition/Mutex in the Zig code base.

Welcome to the forum, btw!

3 Likes