当前位置: 首页 > news >正文

网站公众号信息化建设工作计划网站建设类文章要发多少片

网站公众号信息化建设工作计划,网站建设类文章要发多少片,wordpress破解版下载地址,河南艾特软件 网站建设“ WithCancel可以将一个Context包装为cancelCtx,并提供一个取消函数,调用这个取消函数,可以Cancel对应的Context Go语言context包-cancelCtx[1] 疑问 context.WithCancel()取消机制的理解[2] 父母5s钟后出门#xff0c;倒计时#xff0c;父母在时要学习#xff0c;父母一走… “ WithCancel可以将一个Context包装为cancelCtx,并提供一个取消函数,调用这个取消函数,可以Cancel对应的Context Go语言context包-cancelCtx[1] 疑问 context.WithCancel()取消机制的理解[2] 父母5s钟后出门倒计时父母在时要学习父母一走就可以玩 package mainimport ( context fmt time)func dosomething(ctx context.Context) { for {  select {  case -ctx.Done():   fmt.Println(playing)   return  default:   fmt.Println(I am working!)   time.Sleep(time.Second)  } }}func main() { ctx, cancelFunc : context.WithCancel(context.Background()) go func() {  time.Sleep(5 * time.Second)  cancelFunc() }() dosomething(ctx)} 为什么调用cancelFunc就能从ctx.Done()里取得返回值? 进而取消对应的Context 复习一下channel的一个特性 从一个已经关闭的channel里可以一直获取对应的零值 WithCancel代码分析 pkg.go.dev/context#WithCancel:[3] // WithCancel returns a copy of parent with a new Done channel. The returned// contexts Done channel is closed when the returned cancel function is called// or when the parent contexts Done channel is closed, whichever happens first.//// Canceling this context releases resources associated with it, so code should// call cancel as soon as the operations running in this Context complete.//WithCancel 返回具有新 Done 通道的 parent 副本。 返回的上下文的完成通道在调用返回的取消函数或父上下文的完成通道关闭时关闭以先发生者为准。//取消此上下文会释放与其关联的资源因此代码应在此上下文中运行的操作完成后立即调用取消。func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { if parent  nil {  panic(cannot create context from nil parent) } c : newCancelCtx(parent)   // 将parent作为父节点context 生成一个新的子节点 //获得“父Ctx路径”中可被取消的Ctx //将child canceler加入该父Ctx的map中 propagateCancel(parent, c) return c, func() { c.cancel(true, Canceled) }} WithCancel最后返回 子上下文和一个cancelFunc函数而cancelFunc函数里调用了cancelCtx这个结构体的方法cancel (代码基于go 1.16 1.17有所改动) // A cancelCtx can be canceled. When canceled, it also cancels any children// that implement canceler.type cancelCtx struct { Context mu       sync.Mutex            // protects following fields done     chan struct{}         // created lazily, closed by first cancel call done是一个channel用来 传递关闭信号 children map[canceler]struct{} // set to nil by the first cancel call  children是一个map存储了当前context节点下的子节点 err      error                 // set to non-nil by the first cancel call  err用于存储错误信息 表示任务结束的原因} 在cancelCtx这个结构体中字段done是一个传递空结构体类型的channel用来在上下文取消时关闭这个通道err就是在上下文被取消时告诉用户这个上下文取消了可以用ctx.Err()来获取信息 canceler是一个实现接口用于Ctx的终止。实现该接口的Context有cancelCtx和timerCtx而emptyCtx和valueCtx没有实现该接口。 // A canceler is a context type that can be canceled directly. The// implementations are *cancelCtx and *timerCtx.type canceler interface { cancel(removeFromParent bool, err error) Done() -chan struct{}} // closedchan is a reusable closed channel.var closedchan  make(chan struct{})func init() { close(closedchan)}// cancel closes c.done, cancels each of cs children, and, if// removeFromParent is true, removes c from its parents children./*** 1、cancel(...)当前Ctx的子节点* 2、从父节点中移除该Ctx**/func (c *cancelCtx) cancel(removeFromParent bool, err error) { if err  nil {  panic(context: internal error: missing cancel error) } c.mu.Lock() if c.err ! nil {  c.mu.Unlock()  return // already canceled } // 设置取消原因 c.err  err //  设置一个关闭的channel或者将done channel关闭用以发送关闭信号 if c.done  nil {  c.done  closedchan } else {  close(c.done) // 注意这一步 }  // 将子节点context依次取消 for child : range c.children {  // NOTE: acquiring the childs lock while holding parents lock.  child.cancel(false, err) } c.children  nil c.mu.Unlock() if removeFromParent {   // 将当前context节点从父节点上移除  removeChild(c.Context, c) }} 对于cancel函数其取消了基于该上下文的所有子上下文以及把自身从父上下文中取消 对于更多removeFromParent代码分析,和其他Context的使用强烈建议阅读 深入理解Golang之Context可用于实现超时机制[4]  // Done is provided for use in select statements: // //  // Stream generates values with DoSomething and sends them to out //  // until DoSomething returns an error or ctx.Done is closed. //  func Stream(ctx context.Context, out chan- Value) error { //   for { //    v, err : DoSomething(ctx) //    if err ! nil { //     return err //    } //    select { //    case -ctx.Done(): //     return ctx.Err() //    case out - v: //    } //   } //  } // // See https://blog.golang.org/pipelines for more examples of how to use // a Done channel for cancellation. Done() -chan struct{} // If Done is not yet closed, Err returns nil. // If Done is closed, Err returns a non-nil error explaining why: // Canceled if the context was canceled // or DeadlineExceeded if the contexts deadline passed. // After Err returns a non-nil error, successive calls to Err return the same error. Err() error 当调用cancelFunc()时会有一步close(d)的操作, ctx.Done 获取一个只读的 channel类型为结构体。可用于监听当前 channel 是否已经被关闭。 Done()用来监听cancel操作(对于cancelCtx)或超时操作(对于timerCtx)当执行取消操作或超时时c.done会被close这样就能从一个已经关闭的channel里一直获取对应的零值-ctx.Done便不会再阻塞 (代码基于go 1.16 1.17有所改动) func (c *cancelCtx) Done() -chan struct{} { c.mu.Lock() if c.done  nil {  c.done  make(chan struct{}) } d : c.done c.mu.Unlock() return d}func (c *cancelCtx) Err() error { c.mu.Lock() err : c.err c.mu.Unlock() return err} 总结一下使用context.WithCancel时除了返回一个新的context.Context(上下文)还会返回一个cancelFunc。 在需要取消该context.Context时就调用这个cancelFunc,之后当前上下文及其子上下文都会被取消所有的 Goroutine 都会同步收到这一取消信号 至于cancelFunc是如何做到的 在用户代码for循环里select不断尝试从 -ctx.Done()里读取出内容但此时并没有任何给 c.done这个channel写入数据的操作类似c.done - struct{}{},故而在for循环里每次select时这个case都不满足条件一直阻塞着。每次都执行default代码段 而在执行cancelFunc时 在func (c *cancelCtx) cancel(removeFromParent bool, err error)里面会有一个close(c.done)的操作。而从一个已经关闭的channel里可以一直获取对应的零值即 select可以命中进入case res : -ctx.Done():代码段 可用如下代码验证 package mainimport ( context fmt time)func dosomething(ctx context.Context) { var cuiChan  make(chan struct{}) go func() {  cuiChan - struct{}{} }() //close(cuiChan) for {  select {  case res : -ctx.Done():   fmt.Println(res:, res)   return  case res2 : -cuiChan:   fmt.Println(res2:, res2)  default:   fmt.Println(I am working!)   time.Sleep(time.Second)  } }}func main() { test() ctx, cancelFunc : context.WithCancel(context.Background()) go func() {  time.Sleep(5 * time.Second)  cancelFunc() }() dosomething(ctx)}func test() { var testChan  make(chan struct{}) if testChan  nil {  fmt.Println(make(chan struct{})后为nil) } else {  fmt.Println(make(chan struct{})后不为nil) }} 输出 make(chan struct{})后不为nilI am working!res2: {}I am working!I am working!I am working!I am working!res: {} 而如果 不向没有缓存的cuiChan写入数据直接close即 package mainimport ( context fmt time)func dosomething(ctx context.Context) { var cuiChan  make(chan struct{}) //go func() { // cuiChan - struct{}{} //}() close(cuiChan) for {  select {  case res : -ctx.Done():   fmt.Println(res:, res)   return  case res2 : -cuiChan:   fmt.Println(res2:, res2)  default:   fmt.Println(I am working!)   time.Sleep(time.Second)  } }}func main() { test() ctx, cancelFunc : context.WithCancel(context.Background()) go func() {  time.Sleep(5 * time.Second)  cancelFunc() }() dosomething(ctx)}func test() { var testChan  make(chan struct{}) if testChan  nil {  fmt.Println(make(chan struct{})后为nil) } else {  fmt.Println(make(chan struct{})后不为nil) }} 则会一直命中case 2 res2: {}res2: {}res2: {}res2: {}res2: {}res2: {}res2: {}...//一直打印下去 更多参考 深入理解Golang之Context可用于实现超时机制[5] 回答我停止 Goroutine 有几种方法 golang context的done和cancel的理解 for循环channel实现context.Done()阻塞输出[6] 更多关于channel阻塞与close的代码 package mainimport ( fmt time)func main() { ch : make(chan string, 0) go func() {  for {   fmt.Println(----开始----)   v, ok : -ch   fmt.Println(v,ok, v, ok)   if !ok {    fmt.Println(结束)    return   }   //fmt.Println(v)  } }() fmt.Println(-ch一直没有东西写进去会一直阻塞着,直到3秒钟后) fmt.Println() fmt.Println() time.Sleep(3 * time.Second) ch - 向ch这个channel写入第一条数据... ch - 向ch这个channel写入第二条数据 close(ch) // 当channel被close后 v,ok 中的ok就会变为false time.Sleep(10 * time.Second)} 输出为 ----开始-----ch一直没有东西写进去会一直阻塞着,直到3秒钟后v,ok 向ch这个channel写入第一条数据... true----开始----v,ok 向ch这个channel写入第二条数据 true----开始----v,ok  false结束 package mainimport ( fmt sync/atomic time)func main() { ch : make(chan string, 0) done : make(chan struct{}) go func() {  var i int32  for {   atomic.AddInt32(i, 1)   select {   case ch - fmt.Sprintf(%s%d%s, 第, i, 次向通道中写入数据):   case -done:    close(ch)    return   }   // select随机选择满足条件的case并不按顺序所以打印出的结果在30几次波动   time.Sleep(100 * time.Millisecond)  } }() go func() {  time.Sleep(3 * time.Second)  done - struct{}{} }() for i : range ch {  fmt.Println(接收到的值: , i) } fmt.Println(结束)} 输出为 接收到的值:  第1次向通道中写入数据接收到的值:  第2次向通道中写入数据接收到的值:  第3次向通道中写入数据接收到的值:  第4次向通道中写入数据接收到的值:  第5次向通道中写入数据接收到的值:  第6次向通道中写入数据接收到的值:  第7次向通道中写入数据接收到的值:  第8次向通道中写入数据接收到的值:  第9次向通道中写入数据接收到的值:  第10次向通道中写入数据接收到的值:  第11次向通道中写入数据接收到的值:  第12次向通道中写入数据接收到的值:  第13次向通道中写入数据接收到的值:  第14次向通道中写入数据接收到的值:  第15次向通道中写入数据接收到的值:  第16次向通道中写入数据接收到的值:  第17次向通道中写入数据接收到的值:  第18次向通道中写入数据接收到的值:  第19次向通道中写入数据接收到的值:  第20次向通道中写入数据接收到的值:  第21次向通道中写入数据接收到的值:  第22次向通道中写入数据接收到的值:  第23次向通道中写入数据接收到的值:  第24次向通道中写入数据接收到的值:  第25次向通道中写入数据接收到的值:  第26次向通道中写入数据接收到的值:  第27次向通道中写入数据接收到的值:  第28次向通道中写入数据接收到的值:  第29次向通道中写入数据接收到的值:  第30次向通道中写入数据接收到的值:  第31次向通道中写入数据结束 每次执行打印出的结果在30几次波动 参考资料 [1] Go语言context包-cancelCtx: https://dashen.tech/2019/06/23/Go%E8%AF%AD%E8%A8%80context%E5%8C%85/#cancelCtx [2] context.WithCancel()取消机制的理解: https://blog.csdn.net/weixin_42216109/article/details/123694275 [3] pkg.go.dev/context#WithCancel:: https://pkg.go.dev/context#WithCancel [4] 深入理解Golang之Context可用于实现超时机制: https://blog.csdn.net/qq_25821689/article/details/105850717 [5] 深入理解Golang之Context可用于实现超时机制: https://blog.csdn.net/qq_25821689/article/details/105850717 [6] golang context的done和cancel的理解 for循环channel实现context.Done()阻塞输出: https://blog.csdn.net/nakeer/article/details/120897267 本文由 mdnice 多平台发布
http://www.zqtcl.cn/news/429755/

相关文章:

  • 品牌网站开发普通人做电商赚钱吗
  • 网站建设与维护理解视频当背景图片 网站开发
  • 站酷设计师网站wordpress 设置静态内容缓存时间
  • 网站推广做什么好看的电商网站模板下载
  • 如何打破违法网站wordpress 无法上传文件
  • 自己做网站的软件下载wordpress发布文章 更新失败
  • 电大企业网站建设论文范文搜狗推广登录入口
  • 建设银行u盾用网站打不开软件工程师证书有哪些
  • 网站建设域名的购买多少钱注册的公司才能参加投标
  • 做婚纱网站策划方案php网站超市源码
  • 济南网站搭建公司有哪些做企业网站的
  • 360做企业网站多少钱凡客诚品网
  • 效果好的徐州网站建设LAMP环境wordpress放在哪里
  • 考试类网站如何做什么是网络营销?有何特点
  • 网站制作公司哪家好wordpress插件怎么汉化
  • 南阳东莞网站建设公司网页升级访问狼在线观看
  • 备案的网站每年都要备案么东平县建设局网站
  • 做网站必须得ipc手机网站制作方法
  • 山东省建设监理协会网站打不开移动互联网开发实践
  • 南宁微网站制作需要多少钱小米商城网站开发文档
  • 制作销售网站有哪些如何制作个人网页设计
  • 新网站做内链智能网站推广软件
  • 西宁市住房和城乡建设局网站广州站是指哪个站
  • 帮建网站网页设计师考试内容
  • seo网站开发txt 发布 wordpress
  • 资讯门户类网站模板定制系统开发公司
  • 让网站快速收录初中毕业如何提升学历
  • 石家庄做网站价格seo优化效果
  • 为什么浏览器打开是2345网址导航seo免费资源大全
  • 网站工程是干啥的动态个人网页制作html教程