您现在的位置是:首页 > 网络趣梗网络趣梗

channel的中文意思(channel的例句)

2022-09-04 21:58:17网络趣梗0人已围观

简介  channel的中文意思(channel的例句),新营销网红网本栏目通过数据整理汇集了channel的中文意思(channel的例句)相关信息,下面一起看看

  channel的中文意思(channel的例句),新营销网红网本栏目通过数据整理汇集了channel的中文意思(channel的例句)相关信息,下面一起看看。

  本文总结了11种常见的渠道操作。从更高的角度看渠道,会让你对渠道有更全面的了解。

  在介绍11种操作之前,先简单介绍一下通道的使用场景、基本操作和注意事项。

  通道的使用场景使用数据流动的通道:

  邮件传递,邮件过滤

  信号广播

  事件和广播

  请求和响应转发

  任务分配

  结果摘要

  并发控制

  同步和异步

   …

  通道的基本操作和注意事项通道有三种状态:

   Nil,未初始化状态,仅声明,或手动赋值为nil。

  活动、正常通道、可读或可写。

  关了,关了,关了通道之后不要误认为是nil。

  通道可以执行三种操作:

  阅读

  写

  关闭

  这三种操作和三种通道状态可以组合成九种情况:

  恐慌行动频道正常。通道ch成功阻塞或读取为零。ch-阻塞成功或阻塞死机关闭(ch)死机成功。

  对于零通道的情况,不完全遵循上表。有一个特殊的场景:当nil通道处于select的情况下,这个情况会阻塞,但不会造成死锁。

  请参考代码:https://dave.cheney.net/2014/03/19/channel-axioms.

  以下是使用频道的10种常见操作。

   1.用于范围读取通道场景

  当您需要不断地从通道中读取数据时。

  原则

  使用for-range读取通道,既安全又方便。当通道关闭时,for循环会自动退出,不需要主动监控通道是否关闭,可以防止关闭的通道被读取,导致读取的数据为通道中存储的数据类型的零值。

  使用

   x :=range ch { fmt . println(x)} 2。使用v,ok :=-ch select操作确定通道是否关闭场景。

   v,ok :=-ch选择操作决定通道是否关闭。

  原则

   ok的结果和意义:

   -`真的:我读了频道数据,不确定是否要关闭。可能通道还有保存的数据,但是通道关闭了。-`false `:通道关闭,不读取数据。从关闭的通道中读取的值是通道传输的数据类型的零值,该值可能是发送方发送的,也可能是通道关闭。

   _,ok :=-ch与select一起使用。当ok为假时,意味着通道已经关闭。原因解释如下。_,ok :=-ch对应的函数是funcchan recv (c * h chan,epunsafe.pointer,block bool)(选中,收到bool)。参考块表示当前goroutine是否可以被阻塞。block为false时,表示选择操作,当前goroutine的通道中的操作不能被阻塞;否则,这是正常操作(即_,ok不在选择中)。选择的返回值代表当前操作是否成功,主要针对选择服务,接收的返回值代表是否从通道读取了有效值。它有三种返回值情况:

   Block为false,即如果通道为空,将返回(false,false),这意味着选择操作失败,没有收到任何值。

  否则,如果通道已经关闭并且没有数据,则接收数据的变量ep被设置为零并返回(true,false),这意味着选择操作成功,但是通道已经关闭并且没有读取有效值。

  否则,在读取有效数据的其他情况下,返回(true,true)。

  我们来考虑_,ok :=-ch和select一起使用的情况。

   1:当chanrecv返回(false,false)时,本质是select操作失败,所以相关case会阻塞,不被执行,如下面的代码:

   funmain(){ ch :=make(chanint)select { casev,ok 3360=-ch 3360 fmt . printf(v 3360% v,ok3360% v \ n,v,ok)default 3360 fmt . println(nothing)/

   funmain(){ ch :=true(chanint)//Add close(ch)select { casev _,ok 3360=-ch 3360 fmt . printf(v 3360% v,ok3360% v \ n,v,ok)//v3366

  最后,当ok为假时,就只有情况2了。这个时候通道肯定已经关闭了,所以我们可以在select中使用它。

  ok判断channel是否已经关闭。

  用法

  下面例子展示了,向channel写数据然后关闭,依然可以从已关闭channel读到有效数据,但channel关闭且没有数据时,读不到有效数据,ok为false,可以确定当前channel已关闭。

  //demo_select6.gofuncmain(){ ch:=make(chanint,1) //发送1个数据关闭channel ch -1 close(ch) print( closechannel\n ) //不停读数据直到channel没有有效数据 for{ select{ casev,ok:= -ch: print( v: ,v, ,ok: ,ok, \n ) if!ok{ print( channelisclose\n ) return default: print( nothing\n )//结果//closechannel//v:1,ok:true//v:0,ok:false//channelisclose

  更多见golang_step_by_step/channel/ok仓库中ok和select的示例,或者阅读channel源码。

  3. 使用select处理多个channel

  场景

  需要对多个通道进行同时处理,但只处理最先发生的channel时

  原理

  select可以同时监控多个通道的情况,只处理未阻塞的case。当通道为nil时,对应的case永远为阻塞,无论读写。特殊关注:普通情况下,对nil的通道写操作是要panic的。

  用法

  //分配job时,如果收到关闭的通知则退出,不分配jobfunc(h*Handler)handle(job*Job){select{caseh.jobCh -job:returncase -h.stopCh:return}}4. 使用channel的声明控制读写权限

  场景

  协程对某个通道只读或只写时

  目的:

  使代码更易读、更易维护,

  防止只读协程对通道进行写数据,但通道已关闭,造成panic。

  用法

  如果协程对某个channel只有写操作,则这个channel声明为只写。

  如果协程对某个channel只有读操作,则这个channe声明为只读。

  //只有generator进行对outCh进行写操作,返回声明// -chanint,可以防止其他协程乱用此通道,造成隐藏bugfuncgenerator(intn) -chanint{outCh:=make(chanint)gofunc(){fori:=0;i i++{outCh -i}}()returnoutCh//consumer只读inCh的数据,声明为 -chanint//可以防止它向inCh写数据funcconsumer(inCh -chanint){forx:=rangeinCh{fmt.Println(x)}}5. 使用缓冲channel增强并发

  场景

  异步

  原理

  有缓冲通道可供多个协程同时处理,在一定程度可提高并发性。

  用法

  //无缓冲ch1:=make(chanint)ch2:=make(chanint,0)//有缓冲ch3:=make(chanint,1)

  //使用5个`do`协程同时处理输入数据functest(){inCh:=generator(100)outCh:=make(chanint,10)fori:=0;i 5;i++{godo(inCh,outCh)}forr:=rangeoutCh{fmt.Println(r)}funcdo(inCh -chanint,outChchan -int){forv:=rangeinCh{outCh -v*v}}6. 为操作加上超时

  场景

  需要超时控制的操作

  原理

  使用select和time.After,看操作和定时器哪个先返回,处理先完成的,就达到了超时控制的效果

  用法

  funcdoWithTimeOut(timeouttime.Duration)(int,error){ select{ caseret:= -do(): returnret,nil case -time.After(timeout): return0,errors.New( timeout )funcdo() -chanint{ outCh:=make(chanint) gofunc(){ //dowork returnoutCh}7. 使用time实现channel无阻塞读写

  场景

  并不希望在channel的读写上浪费时间

  原理

  是为操作加上超时的扩展,这里的操作是channel的读或写

  用法

  funcunBlockRead(chchanint)(xint,errerror){ select{ casex= -ch: returnx,nil case -time.After(time.Microsecond): return0,errors.New( readtimeout )funcunBlockWrite(chchanint,xint)(errerror){ select{ casech -x: returnnil case -time.After(time.Microsecond): returnerrors.New( readtimeout )}

  注:time.After等待可以替换为default,则是channel阻塞时,立即返回的效果

  8. 使用close(ch)关闭所有下游协程

  场景

  退出时,显示通知所有协程退出

  原理

  所有读ch的协程都会收到close(ch)的信号

  用法

  func(h*Handler)Stop(){close(h.stopCh)//可以使用WaitGroup等待所有协程退出//收到停止后,不再处理请求func(h*Handler)loop()error{for{select{casereq:= -h.reqCh:gohandle(req)case -h.stopCh:return}}}9. 使用chan struct{}作为信号channel

  场景

  使用channel传递信号,而不是传递数据时

  原理

  没数据需要传递时,传递空struct

  用法

  //上例中的Handler.stopCh就是一个例子,stopCh并不需要传递任何数据//只是要给所有协程发送退出的信号typeHandlerstruct{stopChchanstruct{}reqChchan*Request}10. 使用channel传递结构体的指针而非结构体

  场景

  使用channel传递结构体数据时

  原理

  channel本质上传递的是数据的拷贝,拷贝的数据越小传输效率越高,传递结构体指针,比传递结构体更高效

  用法

  reqChchan*Request//好过reqChchanRequest11. 使用channel传递channel

  场景

  使用场景有点多,通常是用来获取结果。

  原理

  channel可以用来传递变量,channel自身也是变量,可以传递自己。

  用法

  下面示例展示了有序展示请求的结果,另一个示例可以见另外文章的版本3。

  packagemainimport( fmt math/rand sync time funcmain(){ reqs:=[]int{1,2,3,4,5,6,7,8,9} //存放结果的channel的channel outs:=make(chanchanint,len(reqs)) varwgsync.WaitGroup wg.Add(len(reqs)) for_,x:=rangereqs{ o:=handle( wg,x) outs -o gofunc(){ wg.Wait() close(outs) //读取结果,结果有序 foro:=rangeouts{ fmt.Println( -o)//handle处理请求,耗时随机模拟funchandle(wg*sync.WaitGroup,aint)chanint{ out:=make(chanint) gofunc(){ time.Sleep(time.Duration(rand.Intn(3))*time.Second) out -a wg.Done() returnout} 相关文章

  十大巅峰网游小说(十大公认网游小说神作推荐)

  百度网盘登陆入口(百度网盘共享群的正确使用方法)

  恶人传评价(《恶人传》以暴制暴成了救赎)

  百度网盘登录入口(百度网盘安装方法)

  番禺中学排名(番禺区热门学校盘点)

  马路标志(交通安全标示大全及图解)

  苹果序列号是哪个(iPhone序列号知识扫盲)

  故宫太和殿介绍(故宫的太和殿为什么叫金銮殿)

  东营人均gdp(中国人均GDP前15强城市)

  陆贞原型(陆贞传奇的原型各个奇葩)

  硫酸铜什么颜色(硫酸铜的用途与危害)

  小米平板4参数(小米平板4参数全曝光)

  更多channel的中文意思(channel的例句)相关信息请关注本文章,本文仅仅做为展示!

Tags: 网络趣事  

很赞哦! ()

随机图文

留言与评论 (共有 条评论)
验证码:

本栏推荐