golang sync包

sync

在golang 文檔上,golang不但願經過共享內存來進行進程間的協同操做,而是經過channel的方式來進行,固然,golang也提供了共享內存,鎖等機制進行協同操做的包;golang

互斥鎖: Mutex 和 RWMutex

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

WaitGroup 和Cond

一個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()

使用channel來實現:【併發請求數據,獲取最早返回的那個數據】

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 庫

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)
}
相關文章
相關標籤/搜索