mirror of
https://github.com/DataDog/go-profiler-notes.git
synced 2026-06-21 00:46:51 +08:00
more examples
This commit is contained in:
parent
f0ad919665
commit
1947aedce5
3 changed files with 131 additions and 0 deletions
55
examples/block-vs-mutex/main.go
Normal file
55
examples/block-vs-mutex/main.go
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"runtime/pprof"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := run(); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func run() error {
|
||||||
|
runtime.SetBlockProfileRate(1)
|
||||||
|
runtime.SetMutexProfileFraction(1)
|
||||||
|
|
||||||
|
aquired := make(chan struct{})
|
||||||
|
var m sync.Mutex
|
||||||
|
m.Lock()
|
||||||
|
go func() {
|
||||||
|
<-aquired
|
||||||
|
m.Lock()
|
||||||
|
aquired <- struct{}{}
|
||||||
|
}()
|
||||||
|
aquired <- struct{}{}
|
||||||
|
time.Sleep(time.Nanosecond)
|
||||||
|
m.Unlock()
|
||||||
|
<-aquired
|
||||||
|
|
||||||
|
if err := writeProfile("block"); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err := writeProfile("mutex"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeProfile(name string) error {
|
||||||
|
f, err := os.Create(name + ".pb.gz")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
if err := pprof.Lookup(name).WriteTo(f, 0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
BIN
examples/block/main
Executable file
BIN
examples/block/main
Executable file
Binary file not shown.
76
examples/block/main.go
Normal file
76
examples/block/main.go
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"runtime/pprof"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var foo []string
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
demonstrateSleep()
|
||||||
|
|
||||||
|
f, err := os.Create("block.pb.gz")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
if err := pprof.Lookup("block").WriteTo(f, 0); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func demonstrateSleep() {
|
||||||
|
runtime.SetBlockProfileRate(1)
|
||||||
|
<-time.After(time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
func demonstrateSelect() {
|
||||||
|
runtime.SetBlockProfileRate(1)
|
||||||
|
|
||||||
|
ch1 := make(chan struct{}, 0)
|
||||||
|
ch2 := make(chan struct{}, 1)
|
||||||
|
ch3 := make(chan struct{}, 0)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
ch2 <- struct{}{}
|
||||||
|
}()
|
||||||
|
|
||||||
|
time.Sleep(20 * time.Millisecond)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ch1:
|
||||||
|
case <-ch2:
|
||||||
|
case <-ch3:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func demonstrateSampling() {
|
||||||
|
runtime.SetBlockProfileRate(int(40 * time.Microsecond.Nanoseconds()))
|
||||||
|
for i := 0; i < 10000; i++ {
|
||||||
|
blockMutex(10 * time.Microsecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func blockMutex(d time.Duration) {
|
||||||
|
m := &sync.Mutex{}
|
||||||
|
m.Lock()
|
||||||
|
go func() {
|
||||||
|
spinSleep(d)
|
||||||
|
m.Unlock()
|
||||||
|
}()
|
||||||
|
m.Lock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// spinSleep is a more accurate version of time.Sleep() for short sleep
|
||||||
|
// durations. Accuracy seems to be ~35ns.
|
||||||
|
func spinSleep(d time.Duration) {
|
||||||
|
start := time.Now()
|
||||||
|
n := 0
|
||||||
|
for time.Since(start) < d {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue