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