支持#
Go 软件包:
github.com/fatih/color[8] 是用于输出对应编码颜色的包。
github.com/schollz/progressbar[9] 是用于为执行时间过久的任务创建进度条的包。
github.com/jimlawless/whereami[10] 是用于捕获源代码的文件名、行号、函数等信息的包,这对于改正错误信息十分有用!
github.com/spf13/cobra[11] 是用于更轻松地创建带有输入选项和相关文档的复杂脚本的包。
Go 软件包:
github.com/fatih/color[8] 是用于输出对应编码颜色的包。
github.com/schollz/progressbar[9] 是用于为执行时间过久的任务创建进度条的包。
github.com/jimlawless/whereami[10] 是用于捕获源代码的文件名、行号、函数等信息的包,这对于改正错误信息十分有用!
github.com/spf13/cobra[11] 是用于更轻松地创建带有输入选项和相关文档的复杂脚本的包。

import (
"net/http"
_ "net/http/pprof"
)
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()将以上代码插入程序中 启动之后执行
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30具体使用方法可以help
如果使用top的话就可以查看方法占用了
(pprof) top
Showing nodes accounting for 29.59s, 98.60% of 30.01s total Dropped 35 nodes (cum <= 0.15s)
flat flat% sum% cum cum%
28.98s 96.57% 96.57% 28.98s 96.57% time.Now
0.24s 0.8% 97.37% 0.51s 1.70% runtime.selectgo
0.16s 0.53% 97.90% 0.16s 0.53% memeqbody
0.13s 0.43% 98.33% 0.29s 0.97% runtime.mapaccess2_faststr
0.08s 0.27% 98.60% 29.95s 99.80% example.com//pts/services/monitor.Run如以上就是说monitor.Run方法中使用了select, 然后其中的time.Now被疯狂执行.
package main
import "testing"
func TestHelloWorld(t *testing.T) {
// t.Fatal("not implemented")
path := getCurrentPath()
t.Log("getCurrentPath: ", path)
}package main
import (
"fmt"
"log"
"os"
"path"
"path/filepath"
"runtime"
"strings"
)
func main() {
fmt.Println("getTmpDir(当前系统临时目录) = ", getTmpDir())
fmt.Println("getCurrentAbPathByExecutable(仅支持go build) = ", getCurrentAbPathByExecutable())
fmt.Println("getCurrentAbPathByCaller(仅支持go run) = ", getCurrentAbPathByCaller())
fmt.Println("getCurrentAbPath(最终方案-全兼容) = ", getCurrentAbPath())
fmt.Println("getCurrentPath(runtime.Caller1) = ", getCurrentPath())
}
// 最终方案-全兼容
func getCurrentAbPath() string {
dir := getCurrentAbPathByExecutable()
if strings.Contains(dir, getTmpDir()) {
return getCurrentAbPathByCaller()
}
return dir
}
func getCurrentPath() string {
_, filename, _, _ := runtime.Caller(1)
return path.Dir(filename)
}
// 获取系统临时目录,兼容go run
func getTmpDir() string {
dir := os.Getenv("TEMP")
if dir == "" {
dir = os.Getenv("TMP")
}
res, _ := filepath.EvalSymlinks(dir)
return res
}
// 获取当前执行文件绝对路径
func getCurrentAbPathByExecutable() string {
exePath, err := os.Executable()
if err != nil {
log.Fatal(err)
}
res, _ := filepath.EvalSymlinks(filepath.Dir(exePath))
return res
}
// 获取当前执行文件绝对路径(go run)
func getCurrentAbPathByCaller() string {
var abPath string
_, filename, _, ok := runtime.Caller(0)
if ok {
abPath = path.Dir(filename)
}
return abPath
}ian@ianDebian:~$ ./test
getTmpDir(当前系统临时目录) = .
getCurrentAbPathByExecutable(仅支持go build) = /home/ian
getCurrentAbPathByCaller(仅支持go run) = /home/ian
getCurrentAbPath(最终方案-全兼容) = /home/ian
getCurrentPath(runtime.Caller1) = /home/ian
ian@ianDebian:~$
ian@ianDebian:~$ go run test.go
getTmpDir(当前系统临时目录) = .
getCurrentAbPathByExecutable(仅支持go build) = /tmp/go-build3048077768/b001/exe
getCurrentAbPathByCaller(仅支持go run) = /home/ian
getCurrentAbPath(最终方案-全兼容) = /tmp/go-build3048077768/b001/exe
getCurrentPath(runtime.Caller1) = /home/ian
ian@ianDebian:~$
ian@ianDebian:~$ go test test_test.go test.go -v
=== RUN TestHelloWorld
test_test.go:8: getCurrentPath: /home/ian
--- PASS: TestHelloWorld (0.00s)
PASS
ok command-line-arguments 0.002sxxx替换为具体地址
先贴一个客观的教程文档网站http://www.runoob.com/go/go-slice.html
CSP 模型是“以通信的方式来共享内存”,不同于传统的多线程通 过共享内存来通信。用于描述两个独立的并发实体通过共享的通 讯 channel (管道)进行通信的并发模型。
• G(Goroutine): 即Go协程,每个go关键字都会创建一个协 程。 • M(Machine):工作线程,在Go中称为Machine,数量对应真 实的CPU数(真正干活的对象)。 • P(Processor): 处理器(Go中定义的一个摡念,非CPU), 包含运行Go代码的必要资源,用来调度 G 和 M 之间的关联关 系,其数量可通过 GOMAXPROCS() 来设置,默认为核心数。 M必须拥有P才可以执行G中的代码,P含有一个包含多个G的队 列,P可以调度G交由M执行。
• 队列轮转:P 会周期性的将G调度到M中执行,执行一段时间 后,保存上下文,将G放到队列尾部,然后从队列中再取出一个 G进行调度。除此之外,P还会周期性的查看全局队列是否有G等 待调度到M中执行。 • 系统调用:当G0即将进入系统调用时,M0将释放P,进而某个空 闲的M1获取P,继续执行P队列中剩下的G。M1的来源有可能是 M的缓存池,也可能是新建的。 当G0系统调用结束后,如果有空闲的P,则获取一个P,继续执 行G0。如果没有,则将G0放入全局队列,等待被其他的P调度。 然后M0将进入缓存池睡眠。 ![[goroutine.png]]
type hchan struct {
qcount uint // 队列中的总元素个数
dataqsiz uint // 环形队列大小,即可存放元素的个数
buf unsafe.Pointer // 环形队列指针
elemsize uint16 //每个元素的大小
closed uint32 //标识关闭状态
elemtype *_type // 元素类型
sendx uint // 发送索引,元素写入时存放到队列中的位置
recvx uint // 接收索引,元素从队列的该位置读出
recvq waitq // 等待读消息的goroutine队列
sendq waitq // 等待写消息的goroutine队列
lock mutex //互斥锁,chan不允许并发读写
}// 无缓冲的channel由于没有缓冲发送和接收需要同步
ch := make(chan int)
//有缓冲channel不要求发送和接收操作同步
ch := make(chan int, 2)channel 无缓冲时,发送阻塞直到数据被接收,接收阻塞直到读 到数据;channel有缓冲时,当缓冲满时发送阻塞,当缓冲空时接 收阻塞。