golang併發編程

go

main函數的執行自己就是一個協程,當使用go關鍵字的時候,就會建立一個新的協程golang

channel

channel 管道,用於在多個協程之間傳遞信號緩存

無緩存管道

當對無緩衝通道寫的時候,會一直阻塞等到某個協程對這個緩衝通道讀
阻塞場景:併發

  1. 通道中無數據,但執行讀通道。
  2. 通道中無數據,向通道寫數據,但無協程讀取。

綜上,無緩存通道的讀寫必須同時存在,且讀寫分別在兩個不一樣的協程函數

func main(){
    ch := make(chan int)
    
    go func(ch chan int){
        ch <-222
    }(ch)
    
    println(<-ch)
}

有緩衝管道

有緩存時能夠向通道中寫入數據後直接返回,緩存中有數據時能夠從通道中讀到數據直接返回,這時有緩存通道是不會阻塞的
阻塞場景:指針

  1. 通道的緩存無數據,但執行讀通道。
  2. 通道的緩存已經佔滿,向通道寫數據,但無協程讀。

綜上,有緩衝通道的讀寫必須在兩個不一樣協程code

func main() {
    ch := make(chan int, 1)  //長度爲1的緩衝管道也是有緩衝管道
    ch <- 333
    go func(ch chan int) {
        println(<-ch)
    }(ch)
    ch <- 333
}

sync.Mutex 和 sync.RwMutex

sync.Mutex 併發鎖,一次只能夠加載一個併發鎖 協程

sync.RwMutex 讀寫鎖,一次能夠加載多個讀鎖和一個寫鎖。當寫鎖存在時候,不能再加載讀鎖和寫鎖it

sync.WaitGroup

阻塞等待全部任務完成以後再繼續執行
WaitGroup在不方法中傳遞,須要傳指針class

func main() {
    var wg sync.WaitGroup
    ch := make(chan int, 1000)
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go doSomething(i, &wg, ch)
    }
    wg.Wait()
    fmt.Println("all done")
    for i := 0; i < 1000; i++ {
        dd := <-ch
        fmt.Println("from ch:"+strconv.Itoa(dd))
    }
}

func doSomething(index int, wg  *sync.WaitGroup, ch chan int) {
    defer wg.Done()
    fmt.Println("start done:" + strconv.Itoa(index))
    //time.Sleep(20 * time.Millisecond)
    ch <- index
}
相關文章
相關標籤/搜索