经过通讯来共享内存(Java是经过共享内存来通讯的)缓存
func service() string { time.Sleep(time.Millisecond * 50) return "Done" } func AsyncService() chan string { retCh := make(chan string, 1)//建立一个容量为1元素类型为string的通道 go func() { ret := service() fmt.Println("returned result.") retCh <- ret//将值放入通道retCh中 fmt.Println("service exited.") }() return retCh } func TestAsynService(t *testing.T) { retCh := AsyncService() otherTask() fmt.Println(<-retCh)//从通道retCh中取去出一个值 time.Sleep(time.Second * 1) }
通道建立语法: make(chan 元素类型, 容量),容量是可选值指通道最多能够缓存多少元素值,这个值不能为负数安全
当容量为0时,称为非缓冲通道,大于0时称为缓冲通道less
通道是个队列,遵循先进先出的原则函数
元素值的发送和接受都须要用接收操做符 <-3d
进入通道的并非在接受操做符右边的那个元素,而是它的副本code
缓冲通道:协程
非缓冲通道:blog
func TestSelect(t *testing.T) { select { case ret := <-retCh1://当通道retCh1中有数据时执行 t.Log(ret) case ret := <-retCh2://当通道retCh2中有数据时执行 t.Error("time out") //default不存在 retCh1 retCh2没数据时,协程会处在阻塞状态 default://当通道retCh1,retCh2都没数据时执行 t.Error("error") } }
select { case ret := <-retCh: t.Log(ret) case <-time.After(time.Second * 1): //设置超时时间 t.Error("time out") }
向关闭的通道发送数据,会致使panic, 关闭已经关闭的通道也会致使panic;队列
接收操做是能够感知通道的关闭,并能安全退出内存
v, ok<-ch;ok为bool值, true表示正常接受, false表示通道关闭
全部的channel接收者都会在channel关闭时,马上从阻塞等待中返回且上述 ok值为false,这个广播机制常被利用,进行向多个订阅者同时发送信号。如:退出信号。
channel关闭原则:
(1) 谁建立的channel谁负责关闭 (2) 不要关闭有发送者的channel (3) 做为函数参数的channel最好带方向
代码:
package channel_close import ( "fmt" "sync" "testing" ) //生产者 func dataProducer(ch chan int, wg *sync.WaitGroup) { go func() { for i := 0; i < 10; i++ { ch <- i } close(ch) wg.Done() }() } //接收者 func dataReceiver(ch chan int, wg *sync.WaitGroup) { go func() { for { if data, ok := <-ch; ok { fmt.Println(data) } else { break } } wg.Done() }() } func TestCloseChannel(t *testing.T) { var wg sync.WaitGroup ch := make(chan int) wg.Add(1) dataProducer(ch, &wg) wg.Add(1) dataReceiver(ch, &wg) wg.Wait() }
Context
·根Context:经过context.Background 0建立·
子Context: context.WithCancel(parentContext)建立
ctx, cancel := context.WithCancel(context.Background))
当前Context被取消时,基于他的子context都会被取消
·接收取消通知<-ctx.Done()
咱们前面说的通道都是双向的,即:既能够发也能够收的通道;所谓单项通就是, 只能发坐着只能收
单项通道定义:
//发送通道(只能发不能收) var uselessChan = make(chan<- int, 1) //接收通道(只能收不能发) var uselessChan1 = make(<-chan int, 1)
通道是用来传递数据的,而单项通道是不能传递数据的
**** 码字不易若是对你有帮助请给个关注****
**** 爱技术爱生活 QQ群: 894109590****