A sync.WaitGroup is a way to coordinate multiple goroutines by reporting completion. Since there’s nobody to report completion, it never returns. Wait blocks until the WaitGroup counter is zero.app
package main import "sync" func main() { var wg sync.WaitGroup wg.Add(1) wg.Wait() }
This function tries to select the first case that returns, so it will happily wait forever for nothing to return.less
package main func main() { select{} }
If the lock is already in use, the calling goroutine blocks until the mutex is available.ide
package main import "sync" func main() { var m sync.Mutex m.Lock() m.Lock() }
The same trick works with a sync.RWMutex that has been RLock()’d.oop
Empty channels will block until there is something to receive.ui
package main func main() { c := make(chan struct{}) <-c }
This also works with a nil channel not made with make()this
The easiest way which will use 100% of CPU.code
package main func main() { for {} }
package main func main() { start: goto start }
func main() { defer main() }
This method technically doesn’t block, it just constantly defers to other work if it’s available.blog
package main import "runtime" func main() { for { runtime.Gosched() } }
Same as before, not technically blocking but looping and deferring to other work.ip
package main import "runtime" func main() { foo: runtime.Gosched() goto foo }
This is a bit like shaking your own hand. This function will continually send a useless message to itself until the end of time. The channel send operations are opportunities for the runtime to schedule other goroutines, so this method would not monopolize a single processor.get
package main func main() { c := make(chan struct{}, 1) for { select { case <-c: case c <- struct{}{}: } } }
Sleeping to the maximum time allowed takes quite a long time, roughly 292.4 years. Likely, your code won’t run that long, so I’d consider this equivalent to select{}.
package main import ( "math" "time" ) func main() { <-time.After(time.Duration(math.MaxInt64)) }
package main import ( "os" "os/signal" "syscall" ) func main() { // exit program on ps kill and Ctrl+C... exitc := make(chan os.Signal, 1) signal.Notify(exitc, os.Interrupt, os.Kill, syscall.SIGTERM) // some code or goroutines // ... <-exitc // some cleanup or signal logging and printing }
以上 1-4 之前都好使,如今好像不行了,會報錯。
fatal error: all goroutines are asleep - deadlock! ...