time.Sleep
// Sleep pauses the current goroutine for at least the duration d.
// A negative or zero duration causes Sleep to return immediately.
func Sleep(d Duration)
runtime/time.go
// timeSleep puts the current goroutine to sleep for at least ns nanoseconds.
//go:linkname timeSleep time.Sleep
func timeSleep(ns int64) {
if ns <= 0 {
return
}
gp := getg()
t := gp.timer
if t == nil {
t = new(timer)
gp.timer = t
}
*t = timer{}
t.when = nanotime() + ns
t.f = goroutineReady
t.arg = gp
tb := t.assignBucket()
lock(&tb.lock)
if !tb.addtimerLocked(t) {
unlock(&tb.lock)
badTimer()
}
goparkunlock(&tb.lock, waitReasonSleep, traceEvGoSleep, 2)
}
go:linkname
//go:linkname localname importpath.name
The //go:linkname directive instructs the compiler to use “importpath.name” as the object file symbol name for the variable or function declared as “localname” in the source code. Because this directive can subvert the type system and package modularity, it is only enabled in files that have imported "unsafe".
unsaferuntime/time.gounsafego:linknamelocalnametimeSleepimportpath.nametime.Sleeptime.SleeptimetimeSleepruntimego:linknametimeruntimehack
目录结构如下
➜ demo git:(master) ✗ tree
.
├── linkname
│ └── a.go
├── main.go
└── outer
└── world.go
文件内容 a.go
package linkname
import _ "unsafe"
//go:linkname hello examples/demo/outer.World
func hello() {
println("hello,world!")
}
world.go
package outer
import (
_ "examples/demo/linkname"
)
func World()
main.go
package main
import (
"examples/demo/outer"
)
func main() {
outer.World()
}
运行如下:
# examples/demo/outer
outer/world.go:7:6: missing function body
go build-completeWorld()outer.s
➜ demo git:(master) ✗ tree
.
├── linkname
│ └── a.go
├── main.go
└── outer
├── i.s
└── world.go
输出如下:
hello,world!
参考: