這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Go的運行時的當前設計,假定程式員自己負責檢測何時終止一個goroutine以及何時終止該程式。 可以通過調用os.Exit或從main()函數的返回來以正常方式終止程式。而有時候我們需要的是使程式阻塞在這一行。
使用sync.WaitGroup
一直等待直到WaitGroup等於0
package mainimport "sync"func main() { var wg sync.WaitGroup wg.Add(1) wg.Wait()}
空select
select{}是一個沒有任何case的select,它會一直阻塞
package mainfunc main() { select{}}
死迴圈
雖然能阻塞,但會100%佔用一個cpu。不建議使用
package mainfunc main() { for {}}
用sync.Mutex
一個已經鎖了的鎖,再鎖一次會一直阻塞,這個不建議使用
package mainimport "sync"func main() { var m sync.Mutex m.Lock() m.Lock()}
os.Signal
系統訊號量,在go裡面也是個channel,在收到特定的訊息之前一直阻塞
package mainimport ( "os" "syscall" "os/signal")func main() { sig := make(chan os.Signal, 2) signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT) <-sig}
空channel或者nil channel
channel會一直阻塞直到收到訊息,nil channel永遠阻塞。
package mainfunc main() { c := make(chan struct{}) <-c}
package mainfunc main() { var c chan struct{} //nil channel <-c}
總結
注意上面寫的的代碼大部分不能直接運行,都會panic,提示“all goroutines are asleep - deadlock!”,因為go的runtime會檢查你所有的goroutine都卡住了, 沒有一個要執行。你可以在阻塞代碼前面加上一個或多個你自己商務邏輯的goroutine,這樣就不會deadlock了。
參考
http://pliutau.com/different-ways-to-block-go-runtime-forever/