概念及作用
channel是一個數據類型,用於實現同步,用於兩個協程之間交換數據。goroutine奉行通過通信來共享內存,而不是共享內存來通信。
引用類型channel是CSP模式的具體實現,用於多個goroutine通訊。其內部實現了同步,確保並發安全。
創建及使用
每個channel在創建的時候必須指定一個類型,指定的類型是任意的。
ch := make(chan int) //使用內置的make函數,可以創建一個channel類型
// 發送數據到channel
ch <- 1
// 從channel接受數據
x := <- ch
案例舉例(一)
①創建channel前
package main import ( "fmt"
"time" ) //定義一個打印機,參數為字符串,按每個字符打印 //打印機屬於公共資源
func Printer(str string) { for _, data := range str { fmt.Printf("%c", data) time.Sleep(time.Second) } fmt.Printf("\n") } func person1() { Printer("hello") } func person2() { Printer("world") } func main() { //新建2個協程,代表2個人,2個人同時使用打印機
go person1() go person2() //特地不讓主協程結束,死循環
for { } }
//結果
hwoerllldo //交叉執行
②創建channel后(注意channel變量和調用的先后順序)
package main import ( "fmt"
"time" ) //全局變量,創建一個channel
var ch = make(chan int) //定義一個打印機,參數為字符串,按每個字符打印 //打印機屬於公共資源
func Printer(str string) { for _, data := range str { fmt.Printf("%c", data) time.Sleep(time.Second) } fmt.Printf("\n") } //person1執行完后,才能到person2執行
func person1() { Printer("hello") ch <- 666 //給管道寫數據,發送
} func person2() { <-ch //從管道取數據,接收,如果通道沒有數據他就會阻塞
Printer("world") } func main() { //新建2個協程,代表2個人,2個人同時使用打印機
go person1() go person2() //特地不讓主協程結束,死循環
for { } }
hello
world
案例舉例(二)
package main import ( "fmt" ) func main() { ch := make(chan string) go func() { fmt.Println("aaaaaaaaaa") str := <-ch // 在執行到這一步的時候main goroutine才會停止阻塞 fmt.Println("取出channel的數據" + str) }() fmt.Println("bbbbbbbbbb") ch <- "hello" // 如果沒有其他goroutine來取走這個數據,main goroutine掛起,直到其它gorouteine把數據拿走(這里會暫時阻塞)
fmt.Println("cccccccccc") }
bbbbbbbbbb
aaaaaaaaaa
取出channel的數據hello
cccccccccc
