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  }