seo优化文章网站,海尔网站建设目的,福田网站建设实训步骤,乐山网站开发公司电话包含了go学习笔记,含有channel的基础学习#xff0c;编写数字的平方#xff0c;如何成组的合并channel#xff0c;如何优雅的关闭退出并发协程#xff0c;通道阻塞情况分析#xff0c;channel与哪些变成情况#xff0c;可谓是收藏好文. 文章目录 并发1#xff1a;chann…包含了go学习笔记,含有channel的基础学习编写数字的平方如何成组的合并channel如何优雅的关闭退出并发协程通道阻塞情况分析channel与哪些变成情况可谓是收藏好文. 文章目录 并发1channel的基础学习并发2编写数字的平方并发3组装式编写数字的平方并发4如何关闭退出并发协程并发5通道阻塞情况并发5channel情况汇总 并发1channel的基础学习
func main() {ch : make(chan int, 2)ch - 1ch - 2elem, ok : -chif ok ! true {fmt.Println(channel closed)}fmt.Println(elem)
}一个从channel里读一个从channel里写
func main() {syncChan1 : make(chan struct{}, 1)syncChan2 : make(chan struct{}, 2)go func() {-syncChan1fmt.Println(receive a sync signal and wait a second...[receiver])time.Sleep(time.Second)for {if elem, ok : -strChan; ok {fmt.Println(Received:, elem, [receiver])} else {break}}fmt.Println(stopped [receiver])syncChan2 - struct{}{}}()go func() {for _, elem : range []string{a, b, c, d} {strChan - elemfmt.Println(sent:, elem, [sender])if elem c {syncChan1 - struct{}{} //唤醒接收的go携程fmt.Println(sent a sync signal:, elem, [sender])}}fmt.Println(ait 2 seconds...[sender])time.Sleep(time.Second * 2)close(strChan)syncChan2 - struct{}{}}()-syncChan2-syncChan2
}赋值写入
type Counter struct {count int
}var mapChan2 make(chan map[string]*Counter, 1)func (counter *Counter) String() string {return fmt.Sprintf(counter:%d, counter.count)
}
func main() {syncChan : make(chan struct{}, 2)go func() {for {if elem, ok : -mapChan2; ok {counter : elem[count]counter.count} else {break}}fmt.Println(stopped [receiver])syncChan - struct{}{}}()go func() {countMap : map[string]*Counter{count: Counter{},}for i : 0; i 5; i {mapChan2 - countMaptime.Sleep(time.Millisecond)fmt.Printf(The count map::%v [sender]\n, countMap)}close(mapChan2)syncChan - struct{}{}}()-syncChan-syncChan
}用struct进行通信
func main() {dataChan : make(chan int, 5)syncChan1 : make(chan struct{}, 1)syncChan2 : make(chan struct{}, 2)go func() {-syncChan1for {if elem, ok : -dataChan; ok {fmt.Printf(Received:%d [receiver]\n], elem)} else {break}}fmt.Println(Done [receiver])syncChan2 - struct{}{}}()go func() {for i : 0; i 5; i {dataChan - ifmt.Printf(Sent:%d [sender]\n, i)}close(dataChan)syncChan1 - struct{}{}syncChan2 - struct{}{}}()-syncChan2-syncChan2
}用select case进行读取
func main() {chanCap : 5intChan : make(chan int, chanCap)for i : 0; i chanCap; i {select {case intChan - 1:case intChan - 2:case intChan - 3:}}for i : 0; i chanCap; i {fmt.Println(-intChan)}
}并发2编写数字的平方
func producer(nums ...int) -chan int {out : make(chan int)go func() {defer close(out)for _, n : range nums {out - n}}()return out
}func square(inCh -chan int) -chan int {out : make(chan int)go func() {defer close(out)for n : range inCh {out - n * n}}()return out}func main() {in : producer(1, 2, 3, 4, 5, 6)out : square(in)for ret : range out {fmt.Println(ret)}fmt.Println(done)
}并发3组装式编写数字的平方
func producer(nums ...int) -chan int {out : make(chan int)go func() {defer close(out)for _, n : range nums {out - n}}()return out
}func square(inCh -chan int) -chan int {out : make(chan int)go func() {defer close(out)for n : range inCh {out - n * n}}()return out}func merge(cs ...-chan int) -chan int {out : make(chan int)var wg sync.WaitGroupcollect : func(in -chan int) {defer wg.Done()for n : range in {out - n}}wg.Add(len(cs))for _, c : range cs {go collect(c)}go func() {wg.Wait()close(out)}()return out}
func main() {in : producer(1, 2, 3, 4, 5, 6)c1 : square(in)c2 : square(in)c3 : square(in)for ret : range merge(c1, c2, c3) {fmt.Printf(%3d , ret)}fmt.Println(\ndone)
}
并发4如何关闭退出并发协程
文章链接退出
使用for-range退出使用,ok退出使用退出通道退出
并发5通道阻塞情况
// 场景1
// 通道中无数据但执行读通道func ReadNoDataFromNoBufCh() {noBufCh : make(chan int)-noBufCh //通道中没数据你还读必然阻塞fmt.Println(read from no buffer channel success)}//场景2
//通道中无数据向通道中写数据但无协程读取func WriteNoBufCh() {ch : make(chan int)ch - 1 //通道中无数据向通道写数据但无协程读取fmt.Println(write to no buffer channel success)
}//场景3
//通道的缓存中无数据但执行读通道func ReaNoDataFromBufCh() {noBufCh : make(chan int, 1)-noBufCh //通道中没数据你还读必然阻塞fmt.Println(ReaNoDataFromBufCh)}//场景4
//通道缓存已经占满,向通道写数据,但无协程读func WriteBufChButFull() {ch : make(chan int, 1)ch - 1ch - 2 //通道缓存已经占满,向通道写数据,但无协程读fmt.Println(WriteBufChButFull)
}并发5channel情况汇总
场景原理用法需要不断从channel读取数据时该方法,当channel关闭时,for循环自动退出,可以防止读取已经关闭的channelfor x : range ch {}v,ok : - ch select操作判断channel是否关闭ok为true读到数据,ok为false,没读到数据v,ok : - ch select需要对多个通道进行同时处理,但只处理最先发生的channel时select 可以同时监视多个通道的情况,只处理未阻塞的case当通道为nil时,对应的case永远为阻塞,无论读写,特殊关注:普通情况下,对nil的通道写操作是要panic的select如果协程只读或只写双向通道变成单向通道单向通道只能只读或只写异步有缓冲通道可供多个协程同时处理,在一定程度可提高并发性make(chan int,10)需要超时控制的操作使用select和time.After看操作和定时哪个先返回,处理先完成的,就达到了超时控制的效果case - time.After()并不希望在channel的读写上浪费时间是为操作加上超时的扩展这里的操是channel的读或写case -time.After()退出时显示通道所有协程退出所有读ch协程都会收到close(ch)的信号使用close(ch)关闭所有下游协程使用channel传递信号而不是传递数据时没数据需要传递时,传递空struct使用chan struct{} 作为信号channel使用channel传递结构体数据时channel本质上传递的是数据的拷贝,拷贝的数据越小传输效率越高,传递结构体指针,比传递结构体更高效使用channel传递结构体的指针而非结构体用来获取结果channel可以用来传递变量channel自身也是变量可以传递自己使用channel传递channel