概念及做用安全
channel是一個數據類型,用於實現同步,用於兩個協程之間交換數據。goroutine奉行經過通訊來共享內存,而不是共享內存來通訊。
引用類型channel是CSP模式的具體實現,用於多個goroutine通信。其內部實現了同步,確保併發安全。併發
建立及使用
每一個channel在建立的時候必須指定一個類型,指定的類型是任意的。函數
ch := make(chan int) //使用內置的make函數,能夠建立一個channel類型
// 發送數據到channel
ch <- 1
// 從channel接受數據
x := <- ch
案例舉例(一)spa
①建立channel前code
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
案例舉例(二)blog
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