This commit is contained in:
2020-06-05 15:39:30 -04:00
commit ea398249d4
30 changed files with 1353 additions and 0 deletions

27
examples/cond.go Normal file
View 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
View 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
View 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
View 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()
}

View 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

View 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
View 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