Last active
April 7, 2023 02:40
-
-
Save achille-roussel/d99726b26befa4184406eff1cd36def9 to your computer and use it in GitHub Desktop.
Detect number of goroutines in different state
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"runtime" | |
"strings" | |
"time" | |
) | |
func main() { | |
ch := make(chan struct{}) | |
for i := 0; i < 10; i++ { | |
go func() { <-ch }() | |
} | |
go time.Sleep(time.Second) | |
runtime.Gosched() | |
b := make([]byte, 1024) | |
t := time.Now() | |
runtime.Stack(b, true) | |
d := time.Since(t) | |
running := 0 | |
receive := 0 | |
sleep := 0 | |
for _, line := range strings.Split(string(b), "\n") { | |
if strings.HasPrefix(line, "goroutine ") { | |
switch { | |
case strings.Contains(line, "running"): | |
running++ | |
case strings.Contains(line, "chan receive"): | |
receive++ | |
case strings.Contains(line, "sleep"): | |
sleep++ | |
} | |
} | |
} | |
fmt.Printf(`=== GOROUTINES === | |
chan receive: %d | |
running: %d | |
sleep: %d | |
(%s) | |
`, receive, running, sleep, d) | |
} |
Author
achille-roussel
commented
Apr 7, 2023
Potential states:
https://cs.opensource.google/go/go/+/master:src/runtime/traceback.go;l=1130-1139?q=%5C%22runnable%5C%22&ss=go%2Fgo
var gStatusStrings = [...]string{
_Gidle: "idle",
_Grunnable: "runnable",
_Grunning: "running",
_Gsyscall: "syscall",
_Gwaiting: "waiting",
_Gdead: "dead",
_Gcopystack: "copystack",
_Gpreempted: "preempted",
}
var waitReasonStrings = [...]string{
waitReasonZero: "",
waitReasonGCAssistMarking: "GC assist marking",
waitReasonIOWait: "IO wait",
waitReasonChanReceiveNilChan: "chan receive (nil chan)",
waitReasonChanSendNilChan: "chan send (nil chan)",
waitReasonDumpingHeap: "dumping heap",
waitReasonGarbageCollection: "garbage collection",
waitReasonGarbageCollectionScan: "garbage collection scan",
waitReasonPanicWait: "panicwait",
waitReasonSelect: "select",
waitReasonSelectNoCases: "select (no cases)",
waitReasonGCAssistWait: "GC assist wait",
waitReasonGCSweepWait: "GC sweep wait",
waitReasonGCScavengeWait: "GC scavenge wait",
waitReasonChanReceive: "chan receive",
waitReasonChanSend: "chan send",
waitReasonFinalizerWait: "finalizer wait",
waitReasonForceGCIdle: "force gc (idle)",
waitReasonSemacquire: "semacquire",
waitReasonSleep: "sleep",
waitReasonSyncCondWait: "sync.Cond.Wait",
waitReasonSyncMutexLock: "sync.Mutex.Lock",
waitReasonSyncRWMutexRLock: "sync.RWMutex.RLock",
waitReasonSyncRWMutexLock: "sync.RWMutex.Lock",
waitReasonTraceReaderBlocked: "trace reader (blocked)",
waitReasonWaitForGCCycle: "wait for GC cycle",
waitReasonGCWorkerIdle: "GC worker (idle)",
waitReasonGCWorkerActive: "GC worker (active)",
waitReasonPreempted: "preempted",
waitReasonDebugCall: "debug call",
waitReasonGCMarkTermination: "GC mark termination",
waitReasonStoppingTheWorld: "stopping the world",
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment