package main
import (
"fmt"
"time"
)
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("worker", id, "started job", j)
time.Sleep(time.Second)
fmt.Println("worker", id, "finished job", j)
results <- j * 2
}
}
func main() {
const numJobs = 5
jobs := make(chan int, numJobs)
results := make(chan int, numJobs)
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
for j := 1; j <= numJobs; j++ {
jobs <- j
}
close(jobs)
for a := 1; a <= numJobs; a++ {
<-results
}
}
信号量
package main
import (
"fmt"
"sync"
)
type SafeCounter struct {
v map[string]int
mux sync.Mutex
}
func (c *SafeCounter) Inc(key string) {
c.mux.Lock()
c.v[key]++
c.mux.Unlock()
}
func (c *SafeCounter) Value(key string) int {
c.mux.Lock()
defer c.mux.Unlock()
return c.v[key]
}
func main() {
c := SafeCounter{v: make(map[string]int)}
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
c.Inc("somekey")
wg.Done()
}()
}
wg.Wait()
fmt.Println(c.Value("somekey"))
}
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
var sharedRsc = false
var m = sync.Mutex{}
c := sync.NewCond(&m)
wg.Add(1)
go func() {
defer wg.Done()
c.L.Lock()
for sharedRsc == false {
fmt.Println("goroutine1 waiting")
c.Wait()
}
fmt.Println("goroutine1", sharedRsc)
c.L.Unlock()
}()
wg.Add(1)
go func() {
defer wg.Done()
c.L.Lock()
for sharedRsc == false {
fmt.Println("goroutine2 waiting")
c.Wait()
}
fmt.Println("goroutine2", sharedRsc)
c.L.Unlock()
}()
time.Sleep(2 * time.Second)
c.L.Lock()
fmt.Println("main goroutine ready")
sharedRsc = true
c.Broadcast()
c.L.Unlock()
wg.Wait()
}
同步
package main
import (
"fmt"
"sync"
"time"
)
type SafeCounter struct {
v map[string]int
mux sync.Mutex
cond *sync.Cond
}
func (c *SafeCounter) Inc(key string) {
c.mux.Lock()
c.v[key]++
c.mux.Unlock()
c.cond.Broadcast()
}
func (c *SafeCounter) Value(key string) int {
c.mux.Lock()
defer c.mux.Unlock()
for c.v[key] == 0 {
c.cond.Wait()
}
return c.v[key]
}
func main() {
c := SafeCounter{v: make(map[string]int)}
c.cond = sync.NewCond(&c.mux)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println(c.Value("somekey"))
}()
time.Sleep(time.Second)
c.Inc("somekey")
wg.Wait()
}
生产者消费者
package main
import (
"fmt"
"sync"
)
type Item struct {
value string
}
type Buffer struct {
items []Item
lock sync.Mutex
cond *sync.Cond
}
func NewBuffer() *Buffer {
b := &Buffer{}
b.cond = sync.NewCond(&b.lock)
return b
}
func (b *Buffer) Produce(item Item) {
b.lock.Lock()
b.items = append(b.items, item)
b.lock.Unlock()
b.cond.Broadcast()
}
func (b *Buffer) Consume() Item {
b.lock.Lock()
for len(b.items) == 0 {
b.cond.Wait()
}
item := b.items[0]
b.items = b.items[1:]
b.lock.Unlock()
return item
}
func main() {
b := NewBuffer()
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 10; i++ {
b.Produce(Item{value: fmt.Sprintf("item %d", i)})
}
}()
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 10; i++ {
item := b.Consume()
fmt.Println("consume:", item.value)
}
}()
wg.Wait()
}
读写锁
package main
import (
"fmt"
"sync"
)
type SafeCounter struct {
v map[string]int
mux sync.RWMutex
}
func (c *SafeCounter) Inc(key string) {
c.mux.Lock()
c.v[key]++
c.mux.Unlock()
}
func (c *SafeCounter) Value(key string) int {
c.mux.RLock()
defer c.mux.RUnlock()
return c.v[key]
}
func main() {
c := SafeCounter{v: make(map[string]int)}
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
c.Inc("somekey")
fmt.Println(c.Value("somekey"))
}(i)
}
wg.Wait()
}