赞
踩
通道(channel)就是一个管道,可以想象成Go 协程之间通信的管道,他是一种队列的数据结构,遵循先进先出的规则
每一个通道只能传递一种数据结构的数据,在我们声明的时候,就要指定管道的类型,chan Type 表示Type类型的通道,通道的零值为nil
var channel_name chan channel_type
func channel() {
//声明了一个类型为string的通道,值为nil
var channel chan string
channel =make(chan string)
fmt.Println(channel)
//简单的声明方式
ch :=make(chan string)
}
声明完通道之后,其值为nil,我们不能直接使用,必须先使用make函数对通道进行初始化操作
package main import ( "fmt" "time" ) func channel() { //声明了一个类型为string的通道,值为nil var channel chan string fmt.Println(channel) } func PrintChan(c chan string) { c <- "第七魂技 - 武魂真身" } func ChanTest() { /** 发送数据 channel_name <- data 接收数据 value :=<-channel_name */ //创建一个通道 ch := make(chan string) fmt.Println("第一魂技。。。") //开启协程 go PrintChan(ch) //从通道中获取数据 res := <-ch fmt.Println(res) fmt.Println("第九魂技。。。") //关闭通道 close(ch) _, ok := <-ch //检查通道是否关闭 fmt.Println(ok) /** 无缓冲通道 c :=make(chan int) c :=make(chan int,0) 缓冲通道 c :=make(chan int ,3)//数值 */ c := make(chan int) go func() { fmt.Println("send 1") c <- 1 }() go func() { n := <-c fmt.Println("receive", n) }() time.Sleep(1 * time.Second) } /** 只读通道 <-than 只写通道 chan <- */ type Sender = chan<- string type Receiver = <-chan string func ChanTest01() { //创建一个双向通道 ch := make(chan string) go func() { var sender Sender = ch fmt.Println("即将学习。。。") sender <- "第二魂技-床绕" }() go func() { var receiver Receiver = ch message := <-receiver fmt.Println("开始学习:", message) }() time.Sleep(1 * time.Second) } func RangeChan() { //遍历通道 for range var channel = make(chan int, 5) go LoopPrint(channel) for v := range channel { fmt.Println(v) } channel1 := make(chan bool, 1) var x int for i := 0; i < 1000; i++ { go increment(channel1, &x) } time.Sleep(1 * time.Second) fmt.Println("x=", x) } func LoopPrint(c chan int) { for i := 0; i < 10; i++ { c <- i } close(c) } func increment(ch chan bool, x *int) { ch <- true //不是原子操作,避免多协程进行操作;使用容量为1的通道,达到锁的效果 *x = *x + 1 <-ch } func funcReceiver(c chan bool) { fmt.Println(<-c) } func main() { RangeChan() ch := make(chan bool) //1.开启一个协程,再往管道写入数据,这样就不会产生死锁 go funcReceiver(ch) //2. 把无缓冲通道改为有缓冲通道 ch := make(chan bool, 1) //go funcReceiver(ch) //往通道里写数据 ch <- true //通道里读数据 ---看上去没啥问题,其实会产生死锁 fatal error: all goroutines are asleep - deadlock! fmt.Println(<-ch) }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。