main函數的執行自己就是一個協程,當使用go
關鍵字的時候,就會建立一個新的協程golang
channel 管道,用於在多個協程之間傳遞信號緩存
當對無緩衝通道寫的時候,會一直阻塞等到某個協程對這個緩衝通道讀
阻塞場景:併發
綜上,無緩存通道的讀寫必須同時存在,且讀寫分別在兩個不一樣的協程函數
func main(){ ch := make(chan int) go func(ch chan int){ ch <-222 }(ch) println(<-ch) }
有緩存時能夠向通道中寫入數據後直接返回,緩存中有數據時能夠從通道中讀到數據直接返回,這時有緩存通道是不會阻塞的
阻塞場景:指針
綜上,有緩衝通道的讀寫必須在兩個不一樣協程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 讀寫鎖,一次能夠加載多個讀鎖和一個寫鎖。當寫鎖存在時候,不能再加載讀鎖和寫鎖it
阻塞等待全部任務完成以後再繼續執行
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 }