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

网上做一道题2元的网站无锡产品排名优化

网上做一道题2元的网站,无锡产品排名优化,怎么在微信公众号上做网站,代理注册公司怎么收费文章目录 前言一、单个任务的取消二、 所有任务取消三、Context的出现Context的定义Context使用 总结 前言 在实际的业务种#xff0c;我们可能会有这么一种场景#xff1a;需要我们主动的通知某一个goroutine结束。比如我们开启一个后台goroutine一直做事情#xff0c;比如… 文章目录 前言一、单个任务的取消二、 所有任务取消三、Context的出现Context的定义Context使用 总结 前言 在实际的业务种我们可能会有这么一种场景需要我们主动的通知某一个goroutine结束。比如我们开启一个后台goroutine一直做事情比如监控现在不需要了就需要通知这个监控goroutine结束不然它会一直跑就泄漏了。 我们都知道一个goroutine启动后我们是无法控制他的大部分情况是等待它自己结束那么如果这个goroutine是一个不会自己结束的后台goroutine呢比如监控等会一直运行的。 下面我们分别介绍 chanselect 方式 和 Context方式任务的取消的方法。 一、单个任务的取消 下面的代码代表的场景是一个监控的任务一直在执行中通过一个无缓存信道在接受到bool的值的时候协程内部通过多路复用进入监控停止的逻辑退出任务。 package mainimport (fmttime )func cancel_1(stop chan bool) {stop - true }func monitor(name string, stop chan bool) {for {select {case -stop:fmt.Printf(%v 监控退出停止了...\n, name)returndefault:fmt.Printf(%v, goroutine监控中... \n, name)time.Sleep(2 * time.Second)}} }func main() {stop : make(chan bool)go monitor(1号, stop)time.Sleep(10 * time.Second)fmt.Println(可以了通知监控停止)cancel_1(stop)//为了检测监控过是否停止如果没有监控输出就表示停止了time.Sleep(5 * time.Second) } 代码执行结果如下 [rootwork day01]# go run context.go 1号, goroutine监控中... 1号, goroutine监控中... 1号, goroutine监控中... 1号, goroutine监控中... 1号, goroutine监控中... 可以了通知监控停止 1号 监控退出停止了...现在稍微改造下上面的代码我们再增加几个goroutine。2号3号 。。。 func main() {stop : make(chan bool)go monitor(1号, stop)go monitor(2号, stop)go monitor(3号, stop)......... }再次执行查看结果 [rootwork day01]# go run context.go 3号, goroutine监控中... 1号, goroutine监控中... 2号, goroutine监控中... 3号, goroutine监控中... 1号, goroutine监控中... 2号, goroutine监控中... 2号, goroutine监控中... 1号, goroutine监控中... 3号, goroutine监控中... 1号, goroutine监控中... 3号, goroutine监控中... 2号, goroutine监控中... 1号, goroutine监控中... 2号, goroutine监控中... 3号, goroutine监控中... 可以了通知监控停止 1号 监控退出停止了... 3号, goroutine监控中... 2号, goroutine监控中... 2号, goroutine监控中... 3号, goroutine监控中... 3号, goroutine监控中... 2号, goroutine监控中... 发现这种方式只停了其中的一个任务。其他两个任务还在执行。 如何保证所有的任务都停止呢我们看下一节 二、 所有任务取消 我们改造代码如下 新增一个cancel_2的方法再main函数调用cancel_2。 package mainimport (fmttime )func cancel_1(stop chan bool) {stop - true }func cancel_2(stop chan bool) {close(stop) }func monitor(name string, stop chan bool) {for {select {case -stop:fmt.Printf(%v 监控退出停止了...\n, name)returndefault:fmt.Printf(%v, goroutine监控中... \n, name)time.Sleep(2 * time.Second)}} }func main() {stop : make(chan bool)go monitor(1号, stop)go monitor(2号, stop)go monitor(3号, stop)time.Sleep(10 * time.Second)fmt.Println(可以了通知监控停止)cancel_2(stop)//为了检测监控过是否停止如果没有监控输出就表示停止了time.Sleep(5 * time.Second)} 执行结果如下 [rootwork day01]# go run context.go 3号, goroutine监控中... 1号, goroutine监控中... 2号, goroutine监控中... 2号, goroutine监控中... 1号, goroutine监控中... 3号, goroutine监控中... 1号, goroutine监控中... 2号, goroutine监控中... 3号, goroutine监控中... 3号, goroutine监控中... 1号, goroutine监控中... 2号, goroutine监控中... 1号, goroutine监控中... 2号, goroutine监控中... 3号, goroutine监控中... 可以了通知监控停止 3号 监控退出停止了... 2号 监控退出停止了... 1号 监控退出停止了...可以看到三个goroutine都停止了这里我们用到了关闭通道的广播机制所有通道接收者都会收到关闭的消息。 上面的例子说明当我们定义一个无缓冲通道时如果要对所有的 goroutine 进行关闭可以使用 close 关闭通道然后在所有的 goroutine 里不断检查通道是否关闭(前提你得约定好该通道你只会进行 close 而不会发送其他数据否则发送一次数据就会关闭一个goroutine这样会不符合咱们的预期所以最好你对这个通道再做一层封装做个限制)来决定是否结束 goroutine。 三、Context的出现 前两节chanselect的方式是比较优雅的结束一个goroutine的方式不过这种方式也有局限性如果有很多goroutine都需要控制结束怎么办呢如果这些goroutine又衍生了其他更多的goroutine怎么办呢如果一层层的无穷尽的goroutine呢如下图当取消Handl(Req1)这个节点的任务希望取消与他关联的子任务的时候。我们再通过上面方式是不是就需要修改很多呢。所以Context的真正用途出现了。 Context的定义 Context也叫上下文它的接口定义如下 type Context interface {Deadline() (deadline time.Time, ok bool)Done() -chan struct{}Err() errorValue(key interface{}) interface{} }Deadline返回的第一个值是 截止时间到了这个时间点Context 会自动触发 Cancel 动作。返回的第二个值是 一个布尔值true 表示设置了截止时间false 表示没有设置截止时间如果没有设置截止时间就要手动调用 cancel 函数取消Context。Done返回一个只读的通道只有在被cancel后才会返回类型为 struct{}。当这个通道可读时意味着parent context已经发起了取消请求根据这个信号开发者就可以做一些清理动作退出goroutine。Err返回 context 被 cancel 的原因。Value返回被绑定到 Context 的值是一个键值对所以要通过一个Key才可以获取对应的值这个值一般是线程安全的。 Context使用 使用Context完成 package mainimport (contextfmttime )func monitor(name string, ctx context.Context) {for {select {case -ctx.Done():fmt.Printf(%v 监控退出停止了...\n, name)returndefault:fmt.Printf(%v, goroutine监控中... \n, name)time.Sleep(2 * time.Second)}} }func main() {ctx, cancel : context.WithCancel(context.Background())go monitor(1号, ctx)go monitor(2号, ctx)go monitor(3号, ctx)time.Sleep(10 * time.Second)fmt.Println(可以了通知监控停止)cancel()//为了检测监控过是否停止如果没有监控输出就表示停止了time.Sleep(5 * time.Second) }执行结果 [rootwork day01]# go run context2.go 1号, goroutine监控中... 3号, goroutine监控中... 2号, goroutine监控中... 1号, goroutine监控中... 3号, goroutine监控中... 2号, goroutine监控中... 2号, goroutine监控中... 3号, goroutine监控中... 1号, goroutine监控中... 1号, goroutine监控中... 2号, goroutine监控中... 3号, goroutine监控中... 2号, goroutine监控中... 1号, goroutine监控中... 3号, goroutine监控中... 可以了通知监控停止 3号 监控退出停止了... 1号 监控退出停止了... 2号 监控退出停止了...总结 任务的取消一般可以采用chan select方式但是任务依赖比较复杂的情况推荐使用Context通常 Context 都是做为函数的第一个参数进行传递规范性做法并且变量名建议统一叫 ctxContext 是线程安全的可以放心地在多个 goroutine 中使用。当你把 Context 传递给多个 goroutine 使用时只要执行一次 cancel 操作所有的 goroutine 就可以收到 取消的信号当一个 Context 被 cancel 时继承自该 Context 的所有 子 Context 都会被 cancel。
http://www.pierceye.com/news/924636/

相关文章:

  • wordpress 众筹网站模板wordpress首页只显示一篇文章
  • 嘉兴seo网站推广网页设计与制作课程结构
  • 江苏 网站 备案百度站长之家工具
  • 新加坡 网站建设专业简历制作网站有哪些
  • 河北外贸网站建设大连建设网球场价格
  • 北京企业网站制作哪家好新余商城网站建设
  • 网站建设对客户的优势单位建设网站的目的
  • seo网站建站公司的主页珠江夜游微信公众号
  • 建筑人才网 中高端招聘网站专业网站开发开发
  • 江门官网建站公司wordpress get_tax_meta
  • 云南省建设系统网站wordpress wdlog主题
  • 做医疗网站颜色选择网站改版301怎么做
  • 淘宝网站建设步骤做网络网站需要三证么
  • 免费网站域名注册申请视频网站开发策划书
  • 如何在社交网站做销售无锡做网站企业
  • 网站建设首选唯美谷wordpress小程序编辑
  • openwrt 网站开发北京建机职业技能鉴定中心官网
  • 莱芜新站优化wordpress打卡签到领红包
  • wordpress 网站上传到服务器免费在线自助建站
  • 连云港网站优化公司网站优化竞争对手分析
  • 网页设计案例图片网站优化如何收费
  • 个人网站包含哪些内容昆明建企业网站多少钱
  • 摄影作品共享网站开发背景企业互联网服务平台
  • 伍佰亿网站建设礼品回收网站建设
  • 优秀的wordpress涉及seo关键词排名网络公司
  • 徐州免费建站wordpress 宣布停止
  • 黑龙江建设人员证件查询网站北京广告公司地址
  • 建设网站的流程泰安房产网二手房出售
  • 网站开发工具总结互联网营销是做什么
  • 长沙营销型网站开发简单免费模板