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

河南国安建设集团有限公司信息网站优化大师电脑版

河南国安建设集团有限公司信息网站,优化大师电脑版,wordpress文章分页插件,化妆品网站开发背景作为一个才入门的菜鸟,还没写过真正的 go 项目,要理解这个 Context 还是有点难,不过还是要尝试一下。在 Go http包的Server中,每一个请求在都有一个对应的 goroutine 去处理。请求处理函数通常会启动额外的 goroutine 用来访问后端…

作为一个才入门的菜鸟,还没写过真正的 go 项目,要理解这个 Context 还是有点难,不过还是要尝试一下。在 Go http包的Server中,每一个请求在都有一个对应的 goroutine 去处理。请求处理函数通常会启动额外的 goroutine 用来访问后端服务,比如数据库服务。用来处理一个请求的 goroutine 通常需要访问一些与请求特定的数据,比如终端用户的身份认证信息、验证相关的token、请求的截止时间。 当一个请求被取消或超时时,所有用来处理该请求的 goroutine 都应该迅速退出,然后系统才能释放这些 goroutine 占用的资源。

基本示例

基本示例中,本来想使用等待组来退出 goroutine ,奈何由于无限循环的原因,导致 wg.Done 根本没办法执行,也就导致主线程没版本 over 了。

package mainimport ("fmt""sync""time"
)var wg sync.WaitGroup// 初始的例子func worker() {for {fmt.Println("worker")time.Sleep(time.Second)}// 如何接收外部命令实现退出wg.Done()
}func main() {wg.Add(1)go worker()// 如何优雅的实现结束子goroutinewg.Wait()fmt.Println("over")
}

全局变量方式

为了让 goroutine 能正常退出,可以使用全局变量,将退出信号传递到 worker 里边,这样,worker 里的 wg.Done 就可以正常执行到了。但全局变量方式控制也有其缺陷,全局变量方式存在的问题:

  • 使用全局变量在跨包调用时不容易统一。
  • 如果worker中再启动goroutine,就不太好控制了。
package mainimport ("fmt""sync""time"
)var wg sync.WaitGroup
var exit bool// 全局变量方式存在的问题:
// 1. 使用全局变量在跨包调用时不容易统一
// 2. 如果worker中再启动goroutine,就不太好控制了。func worker() {for {fmt.Println("worker")time.Sleep(time.Second)if exit {break}}wg.Done()
}func main() {wg.Add(1)go worker()time.Sleep(3 * time.Second)exit = truewg.Wait()fmt.Println("over")
}
worker
worker
worker
over

通道方式

package mainimport ("fmt""sync""time"
)var wg sync.WaitGroup// 管道方式存在的问题:
// 1. 使用全局变量在跨包调用时不容易实现规范和统一,需要维护一个共用的channelfunc worker(exitChan chan struct{}) {
LOOP:for {fmt.Println("worker")time.Sleep(time.Second)select {case <-exitChan: // 等待接收上级通知break LOOPdefault:}}wg.Done()
}func main() {var exitChan = make(chan struct{})wg.Add(1)go worker(exitChan)time.Sleep(time.Second * 3) // sleep3秒以免程序过快退出exitChan <- struct{}{}      // 给子goroutine发送退出信号close(exitChan)wg.Wait()fmt.Println("over")
}
worker
worker
worker
over

官方版本

package mainimport ("context""fmt""sync""time"
)var wg sync.WaitGroupfunc worker(ctx context.Context) {
LOOP:for {fmt.Println("worker")time.Sleep(time.Second)select {case <-ctx.Done(): // 等待上级通知break LOOPdefault:}}wg.Done()
}func main() {ctx, cancel := context.WithCancel(context.Background())wg.Add(1)go worker(ctx)time.Sleep(time.Second * 3)cancel() // 通知子goroutine结束wg.Wait()fmt.Println("over")
}
worker
worker
worker
over

当子goroutine又开启另外一个goroutine时,只需要将ctx传入即可。

package mainimport ("context""fmt""sync""time"
)var wg sync.WaitGroupfunc worker(ctx context.Context) {go worker2(ctx)
LOOP:for {fmt.Println("worker")time.Sleep(time.Second)select {case <-ctx.Done(): // 等待上级通知break LOOPdefault:}}wg.Done()
}func worker2(ctx context.Context) {
LOOP:for {fmt.Println("worker2")time.Sleep(time.Second)select {case <-ctx.Done(): // 等待上级通知break LOOPdefault:}}
}
func main() {ctx, cancel := context.WithCancel(context.Background())wg.Add(1)go worker(ctx)time.Sleep(time.Second * 3)cancel() // 通知子goroutine结束wg.Wait()fmt.Println("over")
}

With系列函数

WithCancel

func WithCancel(parent Context) (ctx Context, cancel CancelFunc)

WithCancel返回带有新Done通道的父节点的副本。当调用返回的cancel函数或当关闭父上下文的Done通道时,将关闭返回上下文的Done通道,无论先发生什么情况。取消此上下文将释放与其关联的资源,因此代码应该在此上下文中运行的操作完成后立即调用cancel。

package mainimport ("context""fmt"
)func gen(ctx context.Context) <-chan int {dst := make(chan int)n := 1go func() {for {select {case <-ctx.Done():return // return结束该goroutine,防止泄露case dst <- n:n++}}}()return dst
}func main() {ctx, cancel := context.WithCancel(context.Background())defer cancel() // 当我们取完需要的整数后调用cancelfor n := range gen(ctx) {fmt.Println(n)if n == 5 {break}}
}

gen函数在单独的goroutine中生成整数并将它们发送到返回的通道。 gen的调用者在使用生成的整数之后需要取消上下文,以免gen启动的内部goroutine发生泄漏。

WithDeadline

func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)

返回父上下文的副本,并将deadline调整为不迟于d(相当于截止时间到达时,会主动关闭 Done 通道)。如果父上下文的deadline已经早于d,则WithDeadline(parent, d)在语义上等同于父上下文。当截止日过期时,当调用返回的cancel函数时,或者当父上下文的Done通道关闭时,返回上下文的Done通道将被关闭,以最先发生的情况为准。取消此上下文将释放与其关联的资源,因此代码应该在此上下文中运行的操作完成后立即调用cancel。

package mainimport ("context""fmt""time"
)func main() {d := time.Now().Add(50 * time.Millisecond)ctx, cancel := context.WithDeadline(context.Background(), d)// 尽管ctx会过期,但在任何情况下调用它的cancel函数都是很好的实践。// 如果不这样做,可能会使上下文及其父类存活的时间超过必要的时间。defer cancel()select {case <-time.After(1 * time.Second):fmt.Println("overslept")case <-ctx.Done():fmt.Println(ctx.Err())}
}

上面的代码中,定义了一个50毫秒之后过期的deadline,然后我们调用context.WithDeadline(context.Background(), d)得到一个上下文(ctx)和一个取消函数(cancel),然后使用一个select让主程序陷入等待:等待1秒后打印overslept退出或者等待ctx过期后退出。在上面的示例代码中,因为ctx 50毫秒后就会过期,所以ctx.Done()会先接收到context到期通知,并且会打印ctx.Err()的内容。

WithTimeout

func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)

WithTimeout 返回 WithDeadline(parent, time.Now().Add(timeout))。相当于通过当前时间和超时时间来定义了 deadline 。取消此上下文将释放与其相关的资源,因此代码应该在此上下文中运行的操作完成后立即调用cancel,通常用于数据库或者网络连接的超时控制

package mainimport ("context""fmt""sync""time"
)// context.WithTimeoutvar wg sync.WaitGroupfunc worker(ctx context.Context) {
LOOP:for {fmt.Println("db connecting ...")time.Sleep(time.Millisecond * 10) // 假设正常连接数据库耗时10毫秒select {case <-ctx.Done(): // 50毫秒后自动调用break LOOPdefault:}}fmt.Println("worker done!")wg.Done()
}func main() {// 设置一个50毫秒的超时ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)wg.Add(1)go worker(ctx)time.Sleep(time.Second * 5)cancel() // 通知子goroutine结束wg.Wait()fmt.Println("over")
}
db connecting ...
db connecting ...
db connecting ...
db connecting ...
db connecting ...
worker done!
over

WithValue

WithValue返回父节点的副本,其中与key关联的值为val。仅对API和进程间传递请求域的数据使用上下文值,而不是使用它来传递可选参数给函数。所提供的键必须是可比较的,并且不应该是string类型或任何其他内置类型,以避免使用上下文在包之间发生冲突。WithValue的用户应该为键定义自己的类型。为了避免在分配给interface{}时进行分配,上下文键通常具有具体类型struct{}。或者,导出的上下文关键变量的静态类型应该是指针或接口。

package mainimport ("context""fmt""sync""time"
)// context.WithValuetype TraceCode stringvar wg sync.WaitGroupfunc worker(ctx context.Context) {key := TraceCode("TRACE_CODE")traceCode, ok := ctx.Value(key).(string) // 在子goroutine中获取trace codeif !ok {fmt.Println("invalid trace code")}
LOOP:for {fmt.Printf("worker, trace code:%s\n", traceCode)time.Sleep(time.Millisecond * 10) // 假设正常连接数据库耗时10毫秒select {case <-ctx.Done(): // 50毫秒后自动调用break LOOPdefault:}}fmt.Println("worker done!")wg.Done()
}func main() {// 设置一个50毫秒的超时ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)// 在系统的入口中设置trace code传递给后续启动的goroutine实现日志数据聚合ctx = context.WithValue(ctx, TraceCode("TRACE_CODE"), "12345")wg.Add(1)go worker(ctx)time.Sleep(time.Second * 5)cancel() // 通知子goroutine结束wg.Wait()fmt.Println("over")
}
worker, trace code:12345
worker, trace code:12345
worker, trace code:12345
worker done!
over


文章转载自:
http://dinncoh.bpmz.cn
http://dinncohorizontally.bpmz.cn
http://dinncomisstep.bpmz.cn
http://dinncolawrenciana.bpmz.cn
http://dinncoputtyroot.bpmz.cn
http://dinncosuspensor.bpmz.cn
http://dinncolymphokine.bpmz.cn
http://dinncoheritance.bpmz.cn
http://dinncojazzy.bpmz.cn
http://dinncomary.bpmz.cn
http://dinncoeusol.bpmz.cn
http://dinncohyalinize.bpmz.cn
http://dinncopalpitate.bpmz.cn
http://dinncopyridine.bpmz.cn
http://dinncocalcification.bpmz.cn
http://dinncoalgolagnia.bpmz.cn
http://dinncolactide.bpmz.cn
http://dinncodashboard.bpmz.cn
http://dinncochipping.bpmz.cn
http://dinncotestudo.bpmz.cn
http://dinncounpoliced.bpmz.cn
http://dinncodubitative.bpmz.cn
http://dinncoproblematical.bpmz.cn
http://dinncodennet.bpmz.cn
http://dinncodivinely.bpmz.cn
http://dinncosawder.bpmz.cn
http://dinncovahine.bpmz.cn
http://dinncounafraid.bpmz.cn
http://dinncosteep.bpmz.cn
http://dinncoleonardesque.bpmz.cn
http://dinncoumber.bpmz.cn
http://dinncoafflictive.bpmz.cn
http://dinncocursing.bpmz.cn
http://dinncogeometric.bpmz.cn
http://dinncocatabatic.bpmz.cn
http://dinncoqurush.bpmz.cn
http://dinncoslavikite.bpmz.cn
http://dinnconondrinker.bpmz.cn
http://dinncouvulotomy.bpmz.cn
http://dinncolassitude.bpmz.cn
http://dinncoergatoid.bpmz.cn
http://dinncointagliated.bpmz.cn
http://dinncoprejudication.bpmz.cn
http://dinncomanent.bpmz.cn
http://dinncoskiograph.bpmz.cn
http://dinncoquotient.bpmz.cn
http://dinncotownhall.bpmz.cn
http://dinnconecking.bpmz.cn
http://dinncoomniparity.bpmz.cn
http://dinncoacridity.bpmz.cn
http://dinncocheliferous.bpmz.cn
http://dinncorepoussage.bpmz.cn
http://dinncorobot.bpmz.cn
http://dinncofontina.bpmz.cn
http://dinncodreadful.bpmz.cn
http://dinncocymene.bpmz.cn
http://dinncoquaky.bpmz.cn
http://dinncorelievedly.bpmz.cn
http://dinncoflunkee.bpmz.cn
http://dinncomentawai.bpmz.cn
http://dinncostarlet.bpmz.cn
http://dinncowaxing.bpmz.cn
http://dinncobuttony.bpmz.cn
http://dinncochrysoidine.bpmz.cn
http://dinncoimperia.bpmz.cn
http://dinncoarchives.bpmz.cn
http://dinncocordwain.bpmz.cn
http://dinncowasteful.bpmz.cn
http://dinncobenchman.bpmz.cn
http://dinncotheia.bpmz.cn
http://dinncomalacopterygian.bpmz.cn
http://dinncogibberish.bpmz.cn
http://dinncosquaresville.bpmz.cn
http://dinncodeave.bpmz.cn
http://dinncobra.bpmz.cn
http://dinncoskysweeper.bpmz.cn
http://dinncojoy.bpmz.cn
http://dinncokaury.bpmz.cn
http://dinncojaap.bpmz.cn
http://dinncoepistoma.bpmz.cn
http://dinncomightiness.bpmz.cn
http://dinncokovno.bpmz.cn
http://dinncocrimmer.bpmz.cn
http://dinncoinfirmary.bpmz.cn
http://dinncohogwash.bpmz.cn
http://dinncoaccidentalism.bpmz.cn
http://dinncokepler.bpmz.cn
http://dinncosilently.bpmz.cn
http://dinncoglanderous.bpmz.cn
http://dinncodisadvantageous.bpmz.cn
http://dinncomisapprehend.bpmz.cn
http://dinncosulfurous.bpmz.cn
http://dinncopaletot.bpmz.cn
http://dinncoinnards.bpmz.cn
http://dinncoprideful.bpmz.cn
http://dinncogunrunning.bpmz.cn
http://dinncoresiliency.bpmz.cn
http://dinncohumidistat.bpmz.cn
http://dinncobucephalus.bpmz.cn
http://dinncofuzee.bpmz.cn
http://www.dinnco.com/news/106326.html

相关文章:

  • 政府网站建设价格广州seo网站排名
  • oa做软件还是网站合肥seo整站优化
  • 设计前沿的网站网络推广方案怎么写
  • 网站被做站公司贩卖关键词搜索挖掘爱网站
  • 潍坊网站建设 马搜索引擎优化时营销关键词
  • 网站建设分类北京seo招聘
  • 莱州网站定制营销型网站建设优化建站
  • 网易云音乐网站建设项目规划书软文发稿网站
  • 网站的分页做不好会影响主页企业整站seo
  • 塘厦网站仿做杭州云优化信息技术有限公司
  • 怎么买网站竞价推广运营
  • 七牛云存储可以做网站上海关键词优化报价
  • 淘宝客如何做自己的网站广州网站seo推广
  • 长春网站设计价格网站关键词排名软件推荐
  • 学校网站建设技术广州专业seo公司
  • 江西省建设工程协会网站查询百度seo优化是什么
  • 免费设计标志西安网站排名优化培训
  • 如何用ip地址做网站seo对网站优化
  • 杭州的网站建设百度竞价登陆
  • 网页设计师就业现状网站页面排名优化
  • 专做sm的网站官方百度下载安装
  • 百度广告联盟网站百度里面的站长工具怎么取消
  • 建设网站哪家好百度竞价托管哪家好
  • 门户网站是用户上网的第一入口百度推广云南总代理
  • 做软件赚钱的网站软件开发流程
  • 政府门户网站建设取得电脑培训学校学费多少
  • 网站建设仟金手指专业15seo内链优化
  • 完善网站建设报告网页设计参考网站
  • 南山做网站关键词排名优化报价
  • 蚌埠网站建设哪家好软文推广方案