1. Using sync.WaitGroup
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.
package main
import "sync"
func main() {
var wg sync.WaitGroup
wg.Add(1)
wg.Wait()
}
2. Empty select
This function tries to select the first case that returns, so it will happily wait forever for nothing to return.
package main
func main() {
select{}
}
3. Double Locking
If the lock is already in use, the calling goroutine blocks until the mutex is available.
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.
4. Empty Channel
Empty channels will block until there is something to receive.
package main
func main() {
c := make(chan struct{})
<-c
}
This also works with a nil channel not made with make()
5. Infinite loop
The easiest way which will use 100% of CPU.
package main
func main() {
for {}
}
6. goto
package main
func main() {
start:
goto start
}
7. defer
func main() {
defer main()
}
8. Busy Blocking
This method technically doesn’t block, it just constantly defers to other work if it’s available.
package main
import "runtime"
func main() {
for {
runtime.Gosched()
}
}
9. The Decomposed Loop
Same as before, not technically blocking but looping and deferring to other work.
package main
import "runtime"
func main() {
foo:
runtime.Gosched()
goto foo
}
10. Shaking my Own Hand
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.
package main
func main() {
c := make(chan struct{}, 1)
for {
select {
case <-c:
case c <- struct{}{}:
}
}
}
11. Sleeping for a Looooong Time
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))
}
12. Signal
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!
...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。