...
1
2
3
4
5 package semaphore_test
6
7 import (
8 "context"
9 "fmt"
10 "log"
11 "runtime"
12
13 "golang.org/x/sync/semaphore"
14 )
15
16
17
18
19
20
21 func Example_workerPool() {
22 ctx := context.TODO()
23
24 var (
25 maxWorkers = runtime.GOMAXPROCS(0)
26 sem = semaphore.NewWeighted(int64(maxWorkers))
27 out = make([]int, 32)
28 )
29
30
31 for i := range out {
32
33
34 if err := sem.Acquire(ctx, 1); err != nil {
35 log.Printf("Failed to acquire semaphore: %v", err)
36 break
37 }
38
39 go func(i int) {
40 defer sem.Release(1)
41 out[i] = collatzSteps(i + 1)
42 }(i)
43 }
44
45
46
47
48
49 if err := sem.Acquire(ctx, int64(maxWorkers)); err != nil {
50 log.Printf("Failed to acquire semaphore: %v", err)
51 }
52
53 fmt.Println(out)
54
55
56
57 }
58
59
60
61 func collatzSteps(n int) (steps int) {
62 if n <= 0 {
63 panic("nonpositive input")
64 }
65
66 for ; n > 1; steps++ {
67 if steps < 0 {
68 panic("too many steps")
69 }
70
71 if n%2 == 0 {
72 n /= 2
73 continue
74 }
75
76 const maxInt = int(^uint(0) >> 1)
77 if n > (maxInt-1)/3 {
78 panic("overflow")
79 }
80 n = 3*n + 1
81 }
82
83 return steps
84 }
85
View as plain text