init
This commit is contained in:
		
							
								
								
									
										27
									
								
								examples/cond.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								examples/cond.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// START OMIT
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	var v int
 | 
			
		||||
	m := sync.Mutex{}
 | 
			
		||||
	m.Lock() // 1. main process is owner of lock.
 | 
			
		||||
	c := sync.NewCond(&m)
 | 
			
		||||
	go func() {
 | 
			
		||||
		m.Lock() // 4. blocks until Wait(); goroutine then owns lock.
 | 
			
		||||
		v = 1
 | 
			
		||||
		c.Broadcast() // 5. let waiters know we're done.
 | 
			
		||||
		m.Unlock()    // 6. goroutine has released lock.
 | 
			
		||||
	}()
 | 
			
		||||
	v = 0          // 2. do some initialization.
 | 
			
		||||
	c.Wait()       // 3. Temporarily release the lock and block until Broadcast() is called.
 | 
			
		||||
	fmt.Println(v) // 7. prints "1".
 | 
			
		||||
	m.Unlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// END OMIT
 | 
			
		||||
							
								
								
									
										35
									
								
								examples/mutex.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								examples/mutex.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// START OMIT
 | 
			
		||||
 | 
			
		||||
// SafeCounter is safe to use concurrently.
 | 
			
		||||
type SafeCounter struct {
 | 
			
		||||
	V   map[string]int
 | 
			
		||||
	mux sync.Mutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Inc increments the counter for the given key.
 | 
			
		||||
func (c *SafeCounter) Inc(key string) {
 | 
			
		||||
	c.mux.Lock()
 | 
			
		||||
	// Lock so only one goroutine at a time can access the map.
 | 
			
		||||
	defer c.mux.Unlock()
 | 
			
		||||
	c.V[key]++
 | 
			
		||||
	fmt.Println(c.V["key"])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//END OMIT
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	c := &SafeCounter{V: make(map[string]int)}
 | 
			
		||||
	s := sync.WaitGroup{}
 | 
			
		||||
	s.Add(3)
 | 
			
		||||
	go func() { c.Inc("key"); s.Done() }()
 | 
			
		||||
	go func() { c.Inc("key"); s.Done() }()
 | 
			
		||||
	go func() { c.Inc("key"); s.Done() }()
 | 
			
		||||
	s.Wait()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								examples/once.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								examples/once.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// START OMIT
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	var once sync.Once
 | 
			
		||||
	onceBody := func() {
 | 
			
		||||
		fmt.Println("Only once")
 | 
			
		||||
	}
 | 
			
		||||
	done := make(chan bool)
 | 
			
		||||
	for i := 0; i < 10; i++ {
 | 
			
		||||
		go func() {
 | 
			
		||||
			// prints "Only once" once, though Do() is called ten times.
 | 
			
		||||
			once.Do(onceBody)
 | 
			
		||||
			done <- true
 | 
			
		||||
		}()
 | 
			
		||||
	}
 | 
			
		||||
	for i := 0; i < 10; i++ {
 | 
			
		||||
		<-done // wait for all goroutines to finish.
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Println("complete")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// END OMIT
 | 
			
		||||
							
								
								
									
										54
									
								
								examples/rwmutex.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								examples/rwmutex.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// START OMIT
 | 
			
		||||
 | 
			
		||||
// SafeCounter is safe to use concurrently.
 | 
			
		||||
type SafeCounter struct {
 | 
			
		||||
	v   map[string]int
 | 
			
		||||
	mux sync.RWMutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Inc increments the counter for the given key.
 | 
			
		||||
func (c *SafeCounter) Inc(key string) {
 | 
			
		||||
	c.mux.Lock()
 | 
			
		||||
	// Lock so only one goroutine at a time can access the map.
 | 
			
		||||
	defer c.mux.Unlock()
 | 
			
		||||
	c.v[key]++
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Value returns the current value of the counter for the given key.
 | 
			
		||||
func (c *SafeCounter) Value(key string) int {
 | 
			
		||||
	c.mux.RLock()
 | 
			
		||||
	// Many readers can get this lock at once, but Lock() takes priority.
 | 
			
		||||
	defer c.mux.RUnlock()
 | 
			
		||||
	return c.v[key]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//END OMIT
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	c := &SafeCounter{v: make(map[string]int)}
 | 
			
		||||
	s := sync.WaitGroup{}
 | 
			
		||||
	s.Add(3)
 | 
			
		||||
	go func() {
 | 
			
		||||
		c.Inc("key")
 | 
			
		||||
		fmt.Println(c.Value("key"))
 | 
			
		||||
		s.Done()
 | 
			
		||||
	}()
 | 
			
		||||
	go func() {
 | 
			
		||||
		c.Inc("key")
 | 
			
		||||
		fmt.Println(c.Value("key"))
 | 
			
		||||
		s.Done()
 | 
			
		||||
	}()
 | 
			
		||||
	go func() {
 | 
			
		||||
		c.Inc("key")
 | 
			
		||||
		fmt.Println(c.Value("key"))
 | 
			
		||||
		s.Done()
 | 
			
		||||
	}()
 | 
			
		||||
	s.Wait()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								examples/waitgroup-add-misuse.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								examples/waitgroup-add-misuse.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// START OMIT
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	r := []int{1, 2, 3, 4}
 | 
			
		||||
	var group sync.WaitGroup
 | 
			
		||||
	for _, p := range r {
 | 
			
		||||
		group.Add(1)
 | 
			
		||||
		go func(p int) {
 | 
			
		||||
			defer group.Done()
 | 
			
		||||
			fmt.Println(p)
 | 
			
		||||
		}(p)
 | 
			
		||||
		fmt.Println("wait")
 | 
			
		||||
		group.Wait() // HL
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Println("done\n")
 | 
			
		||||
	for _, p := range r {
 | 
			
		||||
		group.Add(1)
 | 
			
		||||
		go func(p int) {
 | 
			
		||||
			defer group.Done()
 | 
			
		||||
			fmt.Println(p)
 | 
			
		||||
		}(p)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Println("wait")
 | 
			
		||||
	group.Wait() // HL
 | 
			
		||||
	fmt.Println("done")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// END OMIT
 | 
			
		||||
							
								
								
									
										25
									
								
								examples/waitgroup-buggy.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								examples/waitgroup-buggy.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// START OMIT
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	var wg sync.WaitGroup
 | 
			
		||||
	for i := 0; i < 10; i++ {
 | 
			
		||||
		wg.Add(1)
 | 
			
		||||
		go func() {
 | 
			
		||||
			defer wg.Done()
 | 
			
		||||
			fmt.Println(i)
 | 
			
		||||
		}()
 | 
			
		||||
	}
 | 
			
		||||
	// wait for all goroutines to finish.
 | 
			
		||||
	fmt.Println("Started all routines")
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
	fmt.Println("Done")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// END OMIT
 | 
			
		||||
							
								
								
									
										25
									
								
								examples/waitgroup.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								examples/waitgroup.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// START OMIT
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	var wg sync.WaitGroup
 | 
			
		||||
	for i := 0; i < 10; i++ {
 | 
			
		||||
		wg.Add(1)
 | 
			
		||||
		go func(routine int) {
 | 
			
		||||
			defer wg.Done()
 | 
			
		||||
			fmt.Println(routine)
 | 
			
		||||
		}(i)
 | 
			
		||||
	}
 | 
			
		||||
	// wait for all goroutines to finish.
 | 
			
		||||
	fmt.Println("Started all routines")
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
	fmt.Println("Done")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// END OMIT
 | 
			
		||||
		Reference in New Issue
	
	Block a user