...
Package semaphore
Package semaphore provides a weighted semaphore implementation.
▾ Example (WorkerPool)
Example_workerPool demonstrates how to use a semaphore to limit the number of
goroutines working on parallel tasks.
This use of a semaphore mimics a typical “worker pool” pattern, but without
the need to explicitly shut down idle workers when the work is done.
Code:
package semaphore_test
import (
"context"
"fmt"
"log"
"runtime"
"golang.org/x/sync/semaphore"
)
func Example_workerPool() {
ctx := context.TODO()
var (
maxWorkers = runtime.GOMAXPROCS(0)
sem = semaphore.NewWeighted(int64(maxWorkers))
out = make([]int, 32)
)
for i := range out {
if err := sem.Acquire(ctx, 1); err != nil {
log.Printf("Failed to acquire semaphore: %v", err)
break
}
go func(i int) {
defer sem.Release(1)
out[i] = collatzSteps(i + 1)
}(i)
}
if err := sem.Acquire(ctx, int64(maxWorkers)); err != nil {
log.Printf("Failed to acquire semaphore: %v", err)
}
fmt.Println(out)
}
func collatzSteps(n int) (steps int) {
if n <= 0 {
panic("nonpositive input")
}
for ; n > 1; steps++ {
if steps < 0 {
panic("too many steps")
}
if n%2 == 0 {
n /= 2
continue
}
const maxInt = int(^uint(0) >> 1)
if n > (maxInt-1)/3 {
panic("overflow")
}
n = 3*n + 1
}
return steps
}
Weighted provides a way to bound concurrent access to a resource.
The callers can request access with a given weight.
type Weighted struct {
}
func NewWeighted(n int64) *Weighted
NewWeighted creates a new weighted semaphore with the given
maximum combined weight for concurrent access.
func (*Weighted) Acquire
¶
func (s *Weighted) Acquire(ctx context.Context, n int64) error
Acquire acquires the semaphore with a weight of n, blocking until resources
are available or ctx is done. On success, returns nil. On failure, returns
ctx.Err() and leaves the semaphore unchanged.
func (*Weighted) Release
¶
func (s *Weighted) Release(n int64)
Release releases the semaphore with a weight of n.
func (s *Weighted) TryAcquire(n int64) bool
TryAcquire acquires the semaphore with a weight of n without blocking.
On success, returns true. On failure, returns false and leaves the semaphore unchanged.