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

Go语言开发小技巧易错点100例(五)

往期回顾:

  • Go语言开发小技巧&易错点100例(一)
  • Go语言开发小技巧&易错点100例(二)
  • Go语言开发小技巧&易错点100例(三)
  • Go语言开发小技巧&易错点100例(四)

本期看点(技巧类用【技】表示,易错点用【易】表示)

(1)pprof查看运行时状态信息【技】

(2)goruntine使用后的销毁【易】

PS:《Go语言开发小技巧&易错点100例》算上这一篇已经完成了20篇啦!五分之一!继续加油

正文如下:

1 pprof查看运行时状态信息

pprof是Go语言的性能分析工具,主要可以分析以下几种情况:

  • allocs:过去所有内存分配的示例
  • block:导致同步原语阻塞的堆栈跟踪
  • cmdline:当前程序的命令行调用
  • goroutine:当前所有goroutine的堆栈跟踪
  • heap:活动对象的内存分配示例。您可以指定gc GET参数,以便在执行堆样例之前运行gc。
  • mutex:竞争互斥对象持有者的堆栈跟踪
  • profile:CPU profile。可以在seconds GET参数中指定持续时间。获得概要文件后,使用go工具pprof命令来研究概要文件。
  • threadcreate:用于创建新的操作系统线程的堆栈跟踪
  • trace:当前程序执行的跟踪。可以在seconds GET参数中指定持续时间。获得跟踪文件后,使用go工具trace命令来调查跟踪。

运行代码:

package main

import (
   "fmt"
   "net/http"
   _ "net/http/pprof"
   "strings"
)

func main() {
   http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
      writer.Write([]byte("Hello~"))
   })     
   http.ListenAndServe(":9090", nil) 
}

访问链接:http://localhost:9090/debug/pprof/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vWPbqALX-1673792495830)(Go语言开发小技巧&易错点100例(五).assets/image-20230115173923597.png)]

2 goruntine使用后的销毁

在上节我们学到了如何去控制goruntine的数量,因为短时间内大量的goroutine同时执行也会造成内存崩溃、CPU占用率过高等问题,不仅如此,当goruntine启动后未进行关闭时,因为大量的挤压goroutine也会造成相同的问题,因此我们要习惯在项目中使用goruntine后进行关闭。

2.1 使用后不销毁出现的问题示例

代码示例:

package main

import (
   "fmt"
   "net/http"
   _ "net/http/pprof"
)

func main() {
   ints := make(chan int,1000)
   i := 0

   worker := func (ch chan int){
      for v := range ch {
         fmt.Println(v)
      }
   }

   http.HandleFunc("/go", func(writer http.ResponseWriter, request *http.Request) {
      i+=1
      ints<-i
      go worker(ints)
   })
   http.ListenAndServe(":9090", nil)
}

查看pprof:

在这里插入图片描述

我们发现同一个地方我们只go出去一次,但是几次请求后还是有很多goruntine,这样如果大批量请求的话一定会出问题。

2.2 使用后销毁的方式

2.2.1 优化代码逻辑

第一种优化方式,就是换一种方式去监听channel:

package main

import (
   "fmt"
   "net/http"
   _ "net/http/pprof"
)


func main() {
   ints := make(chan int,1000)
   i := 0

   worker := func (ch chan int){
      select {
      case v := <-ch:
         fmt.Println(v)
      default:
         return
      }
   }

   http.HandleFunc("/go", func(writer http.ResponseWriter, request *http.Request) {
      i+=1
      ints<-i
      go worker(ints)
   })
   http.ListenAndServe(":9090", nil)
}
2.2.2 利用channel销毁多余的goruntine

第二种方式,我们可以close掉channel来间接的关闭监听他的goruntine

package main

import (
   "fmt"
   "net/http"
   _ "net/http/pprof"
)

func worker(v ...int) {
   count := len(v)
   res :=make(chan int,count)

   go func (ch chan int){
      for i := 0; i < count; i++ {
         fmt.Println(v[i])
         ch <- v[i]
      }
   }(res)

   for i := 0; i < count; i++ {
      <-res
   }

   close(res)
}

func main() {
   val := 0

   http.HandleFunc("/go", func(writer http.ResponseWriter, request *http.Request) {
      val += 1
      go worker(val)
   })
   http.ListenAndServe(":9090", nil)
}
2.2.3 利用Context销毁多余的goruntine

第三种方式,使用Context机制关闭多余的goruntine

相关文章:

  • 怎么介绍自己做的网站/企业网站设计制作
  • 政府部门网站建设内容/公司网络优化方案
  • 如何将公司网站做的更好看/武汉百度推广公司
  • 自己建设网站服务器/自己有网站怎么推广
  • wordpress默认login/seo优化网站查询
  • wordpress网站不收录/网站优化教程
  • 算法leetcode|31. 下一个排列(rust重拳出击)
  • SpringCloud-Netflix学习笔记03——什么是Eureka
  • 测试篇(二): 如何合理的创建bug、bug的级别、bug的生命周期、跟开发产生争执怎么办
  • springboot 项目自定义log日志文件提示系统找不到指定的文件
  • 【数据结构与算法】顺序表的原理及实现
  • 【C进阶】动态内存管理
  • GTD之初总结
  • 【Unity URP】设置光源层Light Layers
  • c语言小练pintia1-10
  • Go语言常量
  • 回首2022展望2023
  • 回归预测 | MATLAB实现SSA-LSSVM麻雀算法优化最小二乘支持向量机多输入单输出