Go

goroutine vs tokio

February 16, 2022
Go, Goroutine, Tokio
Concurrent

Reddit讨论贴 Go uses a different strategy for blocking systemcalls. It does not run them on a threadpool - it moves all the other goroutines that are queued to run on the current thread to a new worker thread, then runs the blocking systemcall on the current thread. This minimizes context switching. You can do this in tokio as well, using task::block_in_place. If I change your code to use that instead of tokio::fs, it gets a lot closer to the go numbers. ...

go runtime chan

February 11, 2022
Go, Runtime, Chan
Chan

src/runtime/chan.go: // Invariants: // At least one of c.sendq and c.recvq is empty, // except for the case of an unbuffered channel with a single goroutine // blocked on it for both sending and receiving using a select statement, // in which case the length of c.sendq and c.recvq is limited only by the // size of the select statement. // // For buffered channels, also: // c.qcount > 0 implies that c. ...

go work

February 10, 2022
Go, Work
Workspace

go1.18将要推出workspace模式,此举是为了方便在本地开发多个不同module时的依赖管理。 命令说明: $ go help work Go workspace provides access to operations on workspaces. Note that support for workspaces is built into many other commands, not just 'go work'. See 'go help modules' for information about Go\'s module system of which workspaces are a part. A workspace is specified by a go.work file that specifies a set of module directories with the "use" directive. These modules are used as root modules by the go command for builds and related operations. ...

Go快速入门

January 25, 2022
Go
Learn

源码 # // 所有代码都需要放到包里 package color // 导入其它包 import ( "context" "fmt" "strconv" "sync" "time" ) // 枚举 type Color int // 常量 const ( Red Color = 1 // 红 Blue Color = 2 // 蓝 Green Color = 3 // 绿 ) // 函数 func NewCar( name string, rate int, ) *Car { return &Car{ name: name, rate: rate, } } // 类型 type Car struct { // 类型字段 name string // 首字母小写,非导出,只能包内使用 rate int } // 类型方法 func (car *Car) String() string { // 首字母大写,导出,可供其它包使用 return "[Car] name: " + car. ...

burn cpu use golang

December 9, 2021
Go
Cpu

虚假的 burn # package main func fakeBurn() { for { } } 真正的 burn # package main import ( "flag" "fmt" "runtime" "time" ) var ( numBurn int updateInterval int ) func cpuBurn() { for { for i := 0; i < 2147483647; i++ { } // Gosched yields the processor, allowing other goroutines to run. It does not suspend the current goroutine, so execution resumes automatically. // Gosched让当前goroutine让出处理器,从而使得其它goroutine可以运行。它不会挂起/暂停当前的goroutine,它会自动恢复执行。 runtime. ...

Go实现AOP

January 17, 2021
Go
Aop, Proxy

AOP # 面向切面编程(AOP: Aspect Oriented Program)。 划分,重复,复用 # 我们知道,面向对象的特点是继承、多态和封装。而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配。实际上也就是说,让不同的类设计不同的方法。这样代码就分散到一个个的类中去了。这样做的好处是降低了代码的复杂程度,使类可重用。 出现的问题: 但是人们也发现,在分散代码的同时,也增加了代码的重复性。什么意思呢?比如说,我们在两个类中,可能都需要在每个方法中做日志。按面向对象的设计方法,我们就必须在两个类的方法中都加入日志的内容。也许他们是完全相同的,但就是因为面向对象的设计让类与类之间无法联系,而不能将这些重复的代码统一起来。 想法1: 也许有人会说,那好办啊,我们可以将这段代码写在一个独立的类独立的方法里,然后再在这两个类中调用。但是,这样一来,这两个类跟我们上面提到的独立的类就有耦合了,它的改变会影响这两个类。 那么,有没有什么办法,能让我们在需要的时候,随意地加入代码呢? 这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。 一般而言,我们管切入到指定类指定方法的代码片段称为切面,而切入到哪些类、哪些方法则叫切入点。 有了AOP,我们就可以把几个类共有的代码,抽取到一个切片中,等到需要时再切入对象中去,从而改变其原有的行为。 OOP从横向上区分出一个个的类来,而AOP则从纵向上向对象中加入特定的代码。 从技术上来说,AOP基本上是通过代理机制实现的。 Go实现AOP – 层间代理 # 假设有store,从数据库获取数据,其中有方法IUserStore.GetByID,传入id参数,返回用户信息: type IUserStore interface { GetByID(ctx context.Context, id int) (User, error) } 另外有service,刚好有用户id并且需要拿到用户信息,于是依赖了上述IUserStore: type IUserSrv interface { CheckUser(ctx context.Context, id int) error // 获取用户信息,然后检查用户某些属性 } type userImpl struct { userStore IUserStore } func (impl userImpl) CheckUser(ctx context.Context, id int) error { user, err := impl.userStore.GetByID(ctx, id) if err ! ...

go ctx

December 18, 2020
Go
Ctx

ctx # 1.why goroutine号称百万之众,互相之间盘根错节,难以管理控制。为此,必须提供一种机制来管理控制它们。 各自为战 # package main import ( "fmt" "time" ) func main() { // start first go func() { fmt.Println(1) }() // start second go func() { fmt.Println(2) }() time.Sleep(time.Second) } 万法归一 # package main import ( "fmt" "sync" ) func main() { wg := new(sync.WaitGroup) // start first wg.Add(1) go func() { defer wg.Done() fmt.Println(1) }() // start second wg.Add(1) go func() { defer wg.Done() fmt. ...