1. 程式人生 > >go語音之進階篇 channel介紹

go語音之進階篇 channel介紹

傳遞 int 讀寫 字符 進階 非阻塞 pac 元素 個人

1、channel介紹

和map類似,channel也一個對應make創建的底層數據結構的引用。

當我們復制一個channel或用於函數參數傳遞時,我們只是拷貝了一個channel引用,因此調用者何被調用者將引用同一個channel對象。和其它的引用類型一樣,channel的零值也是nil。

定義一個channel時,也需要定義發送到channel的值的類型。channel可以使用內置的make()函數來創建:

    make(chan Type) //等價於make(chan Type, 0)
    make(chan Type, capacity)

當 capacity= 0 時,channel 是無緩沖阻塞讀寫的,當capacity> 0 時,channel 有緩沖、是非阻塞的,直到寫滿 capacity個元素才阻塞寫入。

channel通過操作符<-來接收和發送數據,發送和接收數據語法:

    channel <- value      //發送value到channel
    <-channel             //接收並將其丟棄
    x := <-channel        //從channel中接收數據,並賦值給x
    x, ok := <-channel    //功能同上,同時檢查通道是否已關閉或者是否為空

默認情況下,channel接收和發送數據都是阻塞的,除非另一端已經準備好,這樣就使得goroutine同步變的更加的簡單,而不需要顯式的lock。

示例:

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

  

go語音之進階篇 channel介紹