【go的源码阅读】context的实现:context.go

理解Context 这篇文章介绍的很清楚:深入理解Go Context 这个比较详细,但是层次不好:理解GO CONTEXT机制 关于context的使用场景 context的主要使用场景在于:一个任务在处理的过程中可能会启动很多个协程来进行处理。在这个过程中,如果上游的任务想要取消,下游的任务也应当一起取消。context的任务就来了。 内容介绍 context包的内容可以概括为:1个接口,4个实现,6个方法 接口 context.Context 一个接口是指:context.Context type Context interface { Deadline() (deadline time.Time, ok bool) Done() <-chan struct{} Err() error Value(key interface{}) interface{} } Deadline( ) Deadline会返回一个超时时间,Goroutine获得了超时时间后,例如可以对某些io操作设定超时时间。 函数签名 Deadline() (deadline time.Time, ok bool) Deadline 返回的时间 deadline time.Time 代表这个ctx应该被取消的时间。返回的 ok 如果是 false 表示这个context没有设置deadline。连续调用 Deadline 会返回相同的结果。 // Deadline returns the time when work done on behalf of this context // should be canceled. Deadline returns ok==false when no deadline is // set....

July 26, 2024 · 14 min · 2785 words · sirius1y

【go的源码阅读】channel的实现:chan.go

channel的简单使用 在Go语言中,通道(channel)是一种用于在goroutine之间进行通信和同步的机制。下面是一些简单的通道使用示例,以及它们对应的底层函数调用。 package main import ( "fmt" "time" ) func main() { ch := make(chan int) // 创建通道 go func() { ch <- 42 // 发送数据到通道 }() go func() { value := <-ch // 从通道接收数据 fmt.Println("Received:", value) }() time.Sleep(1 * time.Second) // 等待goroutine完成 close(ch) // 关闭通道 } 底层函数调用 创建通道: ch := make(chan int) 底层调用: makechan(elemtype, size) 发送数据到通道: ch <- 42 底层调用: chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool 从通道接收数据:...

May 10, 2024 · 20 min · 4092 words · sirius1y

Go log库,encoding/json

log Go语言内置的log包实现了简单的日志服务。本文介绍了标准库log的基本使用。 Go内置的log库功能有限,例如无法满足记录不同级别日志的情况,我们在实际的项目中根据自己的需要选择使用第三方的日志库,如logrus、zap等。 使用Logger log包定义了Logger类型,该类型提供了一些格式化输出的方法。本包也提供了一个预定义的“标准”logger,可以通过调用函数Print系列(Print|Printf|Println)、Fatal系列(Fatal|Fatalf|Fatalln)、和Panic系列(Panic|Panicf|Panicln)来使用,比自行创建一个logger对象更容易使用。 例如,我们可以像下面的代码一样直接通过log包来调用上面提到的方法,默认它们会将日志信息打印到终端界面: package main import ( &quot;log&quot; ) func main() { log.Println(&quot;这是一条很普通的日志。&quot;) v := &quot;很普通的&quot; log.Printf(&quot;这是一条%s日志。\n&quot;, v) log.Fatalln(&quot;这是一条会触发fatal的日志。&quot;) log.Panicln(&quot;这是一条会触发panic的日志。&quot;) } 编译并执行上面的代码会得到如下输出: 2017/06/19 14:04:17 这是一条很普通的日志。 2017/06/19 14:04:17 这是一条很普通的日志。 2017/06/19 14:04:17 这是一条会触发fatal的日志。 logger会打印每条日志信息的日期、时间,默认输出到系统的标准错误。Fatal系列函数会在写入日志信息后调用os.Exit(1)。Panic系列函数会在写入日志信息后panic。 配置logger 标准logger的配置 默认情况下的logger只会提供日志的时间信息,但是很多情况下我们希望得到更多信息,比如记录该日志的文件名和行号等。log标准库中为我们提供了定制这些设置的方法。 log标准库中的Flags函数会返回标准logger的输出配置,而SetFlags函数用来设置标准logger的输出配置。 func Flags() int func SetFlags(flag int) flag选项 log标准库提供了如下的flag选项,它们是一系列定义好的常量。 const ( // 控制输出日志信息的细节,不能控制输出的顺序和格式。 // 输出的日志在每一项后会有一个冒号分隔:例如2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message Ldate = 1 << iota // 日期:2009/01/23 Ltime // 时间:01:23:23 Lmicroseconds // 微秒级别的时间:01:23:23.123123(用于增强Ltime位) Llongfile // 文件全路径名+行号: /a/b/c/d....

June 22, 2023 · 2 min · 332 words · sirius1y

Go学习笔记

配置 Go 工作区 继续之前,请务必仔细阅读此部分。 Go 在组织项目文件方面与其他编程语言不同。 首先,Go 是在工作区的概念下工作的。 工作区就是应用程序源代码所在的位置。 所有 Go 项目共享同一个工作区。 不过,从版本 1.11 开始,Go 已开始更改此方法。 你尚且不必担心,因为我们将在下一个模块中介绍工作区。 现在,Go 工作区位于 $HOME/go,但如果需要,可以为所有项目设置其他位置。 若要将工作区设置为其他位置,可以使用 $GOPATH 环境变量。 在处理更复杂的项目时,此环境变量有助于避免将来出现问题。 Go 工作区文件夹 每个 Go 工作区都包含三个基本文件夹: bin:包含应用程序中的可执行文件。 src:包括位于工作站中的所有应用程序源代码。 pkg:包含可用库的已编译版本。 编译器可以链接这些库,而无需重新编译它们。 例如,工作站文件夹结构树可能与下面的示例类似: bin/ hello coolapp pkg/ github.com/gorilla/ mux.a src/ github.com/golang/example/ .git/ hello/ hello.go Go实战经验 在命令行中输入’code . ‘会唤起VS code编辑当前目录 源码规范 可执行文件都要包含在package main中 import的包必须都要使用,否则报错不进行编译;vs code中保存文件就会自动调整文件格式,并且删除未使用的import 整个package main中只能有一个func main() 变量的声明和初始化 Go是强类型语言,声明的每个变量都绑定到特定的数据类型,并且只接受与此类型匹配的值。 变量声明的方式有很多,格式和其他语言不太一样 最普通的方式:var 变量名称 变量类型 Go也可以像Python那样自动推断变量的类型,有些时候可以不用加类型名称 最常用的方式(只适用于在函数内,声明并初始化一个新的变量):使用冒号等号 age := 32 注意,在函数体外还是只能用var的方式声明和初始化变量 // 变量声明 // 变量声明了必须要使用,否则编译不通过 var first string var second, third string var age int = 1 var ( fisrtly int = 1 secondly string = 2 thirdly = "123" ) var firstName, secondName, agenumber = "123", "456", 32 // 最常见的声明方式 冒号等于号 := 用于声明并初始化变量,不能用于常量的声明 firstName_, secondName_, age_ := "123", "456", 32 // 常量声明f const HTTPstatusOK = 200 const ( StatusOK = 0 StatusConnectionReset = 1 StatusOtherError = 2 ) 数据类型 基本类型:数字、字符串、布尔值 聚合类型:数组、结构体 引用类型:指针、切片、映射、函数、通道 接口类型:接口 基本类型 在 Go 中,如果你不对变量初始化,所有数据类型都有默认值。...

June 20, 2023 · 5 min · 904 words · sirius1y