在golang 文檔上,golang不但願經過共享內存來進行進程間的協同操做,而是經過channel的方式來進行,固然,golang也提供了共享內存,鎖等機制進行協同操做的包;golang
var m *sync.RWMutex m = new(sync.RWMutex) go m.RLock() // read var m.Unlock() go m.Lock() // write var m.Unlock()
多個goroutine都須要作一個操做,可是這個操做只須要執行一次便可,這就須要Once併發
var once sync.Once for i :=0; i<10; i++{ go func(){ once.Do(func_val) } }
此時多個goroutine只執行一次;atom
一個goroutine等待其餘多個goroutine執行完畢以後才能繼續執行,則這種多協程等待問題須要用WaitGroup
go wp := new(sync.WaitGroup) wp.add(10) for i:=0; i<10; i++{ go func(){ fmt.Println("Done, i=", i) wp.Done() }() } wp.Wait()
sync.Cond用來控制某個條件下,goroutine進行等待時期,等待信號,而後繼續運行:code
locker := new(sync.Mutex) cond := sync.NewCond(locker) done := false cond.L.Lock() go func(){ time.Sleep(2e9) done = true cond.Signal() }() if (!done){ cond.Wait() }
//sync.BroadCast 用來通知喚醒全部等待的goroutine協程
var locker = new(sync.Mutex) var cond = sync.NewCond(locker) func test_function(i int){ cond.L.Lock() cond.Wait() fmt.Println("input value:", i) cond.L.Unlock() //須要釋放lock } for i:=0; i<10; i++{ go test_function(i) } cond.BroadCast()
func Query(conns []Conn, query string) Result{ ch := make(chan Result, 1) for _, c := range conns{ go func(c){ select { case ch <- c.DoQuery(query): default: //case <- timeout , 另開goroutine,進行time.Sleep(10 * time.Second),即超時 } }(conns) } return <-ch }
sync/atomic庫提供了原子 操做的支持,原子操做直接由底層CPU硬件支持;進程
type Value struct{ Key string Value interface{} } type Noaway struct{ Movice atomic.Value Total atomic.Value } func NewNoaway() *Noaway{ n := new(Noaway) n.Movice.Store(&Value{Key: "moive", Val: "Wolf Warrior 2"}) n.Total.Store("$20000") return n } func main(){ n := newNoaway() val := n.Movies.Load().(*Value) total := n.Total.Load().(string) }