golang--通過channel實現goroutine之間的通信

Channel:

一、channel簡介

channel即通道,是goroutine之間溝通的橋樑,大都是阻塞同步的,是引用類型。

1、定義和創建channel;

channel的類型:chan + 數據類型,如:chan bool

創建channel:可以通過make函數來創建channel,第一個參數是channel的類型(如:chan bool),第二個參數是channel的緩存大小(可不填,不填則表示設置緩存爲0)。

示例如下:

var _channel chan bool    //聲明channel

_channel := make(chan bool, 100)    //創建channel

2、通過close關閉;

close(_channel)

3、可以通過for range來迭代操作;

for v := range _channel {
	fmt.Println(v)
}

對線channel進行迭代操作時,必須在迭代的過程中明確關閉這個channel,並且保證channel被關閉成功!【調用close(_channel)】,否則會發生死鎖,導致程序崩潰退出!

報錯提示:fatal error: all goroutines are asleep - deadlock!

4、可以設置單向或雙向通道;

雙向通道:make創建的channel是雙向通道,即channel值既可以存也可以取。

單向通道:分爲兩種:1、channel值只能存;2、channel值只能取。

5、可以設置緩存大小,在未被填滿前不會發生阻塞;

無緩存是同步阻塞的,有緩存是異步的,這一點詳細解釋請看下一章【golang--channel緩存大小與線程阻塞的關係】

 

二、channel的具體操作實例:

1、通過channel來實現線程之間的通信;

完整代碼如下:

package main

import (
	"fmt"
	"time"
)

func main() {
	_channel := make(chan bool)

	go func() {
		fmt.Println("新線程運行開始...")
        //讓線程等待2秒
		time.Sleep(2 * time.Second)
		fmt.Println("新線程運行結束...")
		_channel <- true
	}()
	//main函數運行到這裏,會發生阻塞,直到channel獲得期待的值,纔會繼續往下運行.
	<-_channel
	//由於main函數執行完畢後,函數裏的局部變量都會被釋放,所以我們可以不對channel進行close操作.
	fmt.Println("main函數運行結束...")
}

本例藉助channel實現了main線程與創建的goroutine之間的通信,運行結果如下:

新線程運行開始...
新線程運行結束...
main函數運行結束...

2、對channel進行迭代操作:

package main

import (
	"fmt"
	"time"
)

func main() {
	_channel := make(chan bool)

	go func() {
		fmt.Println("新線程運行開始...")
		//讓線程等待2秒
		time.Sleep(2 * time.Second)
		fmt.Println("新線程運行結束...")
		_channel <- true
		//需要對channel執行關閉操作,否則在main函數中channel會一直進行迭代操作,永遠處於阻塞狀態,進而導致程序崩潰
		close(_channel)
	}()
	//main函數運行到這裏時,會發生阻塞,等待channel獲得期望的值
	for v := range _channel {
		//當channel獲得期望的值時纔會執行到這裏
		fmt.Println("channel的值爲:", v)
	}
	fmt.Println("main函數運行結束...")
}

運行結果如下:

新線程運行開始...
新線程運行結束...
channel的值爲: true
main函數運行結束...

 

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