記錄 go 協程和 channel 中有意思的一個問題

  1. 首先觀察以下代碼,判斷輸出內容或是否報錯

    package main
    import "fmt"
    func main() {
    	var ch chan int
    	var count int
    	go func() {
    		ch <- 1
    	}()
    	go func() {
    		count++
    		close(ch)
    	}()
    	<-ch
    	fmt.Println(count)
    }
    

    該代碼會報錯,原因是 ch 沒有初始化。報錯如下:

    在這裏插入圖片描述

  2. 修改代碼,增加對 ch 初始化,判斷此時代碼的輸出情況

    package main
    import "fmt"
    func main() {
    	var ch chan int
    	ch = make(chan int, 1)
    	var count int
    	go func() {
    		ch <- 1
    	}()
    	go func() {
    		count++
    		close(ch)
    	}()
    	<-ch
    	fmt.Println(count)
    }
    

    繼續報錯,提示 send on closed channel。意思是向以關閉的通道 channel 傳值,報錯如下:

    在這裏插入圖片描述

  3. 繼續修改代碼,去掉 <- ch,判斷輸出是否報錯

    package main
    import "fmt"
    func main() {
    	var ch chan int
    	ch = make(chan int, 1)
    	var count int
    	go func() {
    		ch <- 1
    	}()
    	go func() {
    		count++
    		close(ch)
    	}()
    	fmt.Println(count)
    }
    

    此時不報錯,輸出 0。因爲主程序沒有阻塞,協程和主程序的執行互不干擾。

    在這裏插入圖片描述

  4. 繼續修改代碼,將已刪除的 <- ch 重新添加回來。刪除第二個協程,判斷此時的輸出情況

    package main
    import "fmt"
    func main() {
    	var ch chan int
    	ch = make(chan int, 1)
    	var count int
    	go func() {
    		ch <- 1
    	}()
    	<-ch
    	fmt.Println(count)
    }
    

    此時正常輸出 0。

    在這裏插入圖片描述

  5. 繼續修改代碼,將第二個協程添加回來,刪除第一個協程判斷此時的輸出情況

    package main
    import "fmt"
    func main() {
    	var ch chan int
    	ch = make(chan int, 1)
    	var count int
    	go func() {
    		count++
    		close(ch)
    	}()
    	<-ch
    	fmt.Println(count)
    }
    

    此時輸出 1。

    在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章