Source file src/sync/example_test.go

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package sync_test
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"sync"
    11  )
    12  
    13  type httpPkg struct{}
    14  
    15  func (httpPkg) Get(url string) {}
    16  
    17  var http httpPkg
    18  
    19  // This example fetches several URLs concurrently,
    20  // using a WaitGroup to block until all the fetches are complete.
    21  func ExampleWaitGroup() {
    22  	var wg sync.WaitGroup
    23  	var urls = []string{
    24  		"http://www.golang.org/",
    25  		"http://www.google.com/",
    26  		"http://www.example.com/",
    27  	}
    28  	for _, url := range urls {
    29  		// Launch a goroutine to fetch the URL.
    30  		wg.Go(func() {
    31  			// Fetch the URL.
    32  			http.Get(url)
    33  		})
    34  	}
    35  	// Wait for all HTTP fetches to complete.
    36  	wg.Wait()
    37  }
    38  
    39  // This example is equivalent to the main example, but uses Add/Done
    40  // instead of Go.
    41  func ExampleWaitGroup_addAndDone() {
    42  	var wg sync.WaitGroup
    43  	var urls = []string{
    44  		"http://www.golang.org/",
    45  		"http://www.google.com/",
    46  		"http://www.example.com/",
    47  	}
    48  	for _, url := range urls {
    49  		// Increment the WaitGroup counter.
    50  		wg.Add(1)
    51  		// Launch a goroutine to fetch the URL.
    52  		go func(url string) {
    53  			// Decrement the counter when the goroutine completes.
    54  			defer wg.Done()
    55  			// Fetch the URL.
    56  			http.Get(url)
    57  		}(url)
    58  	}
    59  	// Wait for all HTTP fetches to complete.
    60  	wg.Wait()
    61  }
    62  
    63  func ExampleOnce() {
    64  	var once sync.Once
    65  	onceBody := func() {
    66  		fmt.Println("Only once")
    67  	}
    68  	done := make(chan bool)
    69  	for i := 0; i < 10; i++ {
    70  		go func() {
    71  			once.Do(onceBody)
    72  			done <- true
    73  		}()
    74  	}
    75  	for i := 0; i < 10; i++ {
    76  		<-done
    77  	}
    78  	// Output:
    79  	// Only once
    80  }
    81  
    82  // This example uses OnceValue to perform an "expensive" computation just once,
    83  // even when used concurrently.
    84  func ExampleOnceValue() {
    85  	once := sync.OnceValue(func() int {
    86  		sum := 0
    87  		for i := 0; i < 1000; i++ {
    88  			sum += i
    89  		}
    90  		fmt.Println("Computed once:", sum)
    91  		return sum
    92  	})
    93  	done := make(chan bool)
    94  	for i := 0; i < 10; i++ {
    95  		go func() {
    96  			const want = 499500
    97  			got := once()
    98  			if got != want {
    99  				fmt.Println("want", want, "got", got)
   100  			}
   101  			done <- true
   102  		}()
   103  	}
   104  	for i := 0; i < 10; i++ {
   105  		<-done
   106  	}
   107  	// Output:
   108  	// Computed once: 499500
   109  }
   110  
   111  // This example uses OnceValues to read a file just once.
   112  func ExampleOnceValues() {
   113  	once := sync.OnceValues(func() ([]byte, error) {
   114  		fmt.Println("Reading file once")
   115  		return os.ReadFile("example_test.go")
   116  	})
   117  	done := make(chan bool)
   118  	for i := 0; i < 10; i++ {
   119  		go func() {
   120  			data, err := once()
   121  			if err != nil {
   122  				fmt.Println("error:", err)
   123  			}
   124  			_ = data // Ignore the data for this example
   125  			done <- true
   126  		}()
   127  	}
   128  	for i := 0; i < 10; i++ {
   129  		<-done
   130  	}
   131  	// Output:
   132  	// Reading file once
   133  }
   134  

View as plain text