github.com/glycerine/zebrapack@v4.1.1-0.20181107023619-e955d028f9bf+incompatible/slides/state-of-go/runtime/mutex/main.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "sort" 7 "sync" 8 ) 9 10 func main() { 11 n := flag.Int("n", 10, "maximum number to consider") 12 flag.Parse() 13 14 type pair struct{ n, c int } 15 var pairs []pair 16 for n, c := range countFactorsWideSection(*n) { 17 pairs = append(pairs, pair{n, c}) 18 } 19 sort.Slice(pairs, func(i, j int) bool { return pairs[i].n < pairs[j].n }) 20 for _, p := range pairs { 21 fmt.Printf("%3d: %3d\n", p.n, p.c) 22 } 23 } 24 25 func countFactorsNarrowSection(n int) map[int]int { 26 m := map[int]int{} 27 var mu sync.Mutex 28 var wg sync.WaitGroup 29 30 wg.Add(n - 1) 31 for i := 2; i <= n; i++ { 32 go func(i int) { 33 // NARROW OMIT 34 for _, f := range factors(i) { 35 mu.Lock() // HL 36 m[f]++ 37 mu.Unlock() // HL 38 } 39 wg.Done() 40 }(i) 41 } 42 wg.Wait() 43 return m 44 } 45 46 func countFactorsWideSection(n int) map[int]int { 47 m := map[int]int{} 48 var mu sync.Mutex 49 var wg sync.WaitGroup 50 51 wg.Add(n - 1) 52 for i := 2; i <= n; i++ { 53 go func(i int) { 54 // WIDE OMIT 55 mu.Lock() // HL 56 for _, f := range factors(i) { 57 m[f]++ 58 } 59 mu.Unlock() // HL 60 wg.Done() 61 }(i) 62 } 63 wg.Wait() 64 return m 65 } 66 67 func countFactorsSeq(n int) map[int]int { 68 m := map[int]int{} 69 for i := 2; i <= n; i++ { 70 for _, f := range factors(i) { // HL 71 m[f]++ // HL 72 } // HL 73 } 74 return m 75 } 76 77 func factors(v int) []int { 78 var fs []int 79 for v > 1 { 80 for f := 2; f <= v; f++ { 81 if v%f == 0 { 82 v = v / f 83 fs = append(fs, f) 84 break 85 } 86 } 87 } 88 return fs 89 }