用Golang做一個永久阻塞,你有哪些小技巧
文章來自-微信公眾號: Go語言圈
Go 的執行時的當前設計,假定程式設計師自己負責檢測何時終止一個 goroutine
以及何時終止該程式。可以通過呼叫 os.Exit
或從 main()
函式的返回來以正常方式終止程式。而有時候我們需要的是使程式阻塞在這一行。
使用 sync.WaitGroup
一直等待直到 WaitGroup 等於 0
package main import "sync" func main() { var wg sync.WaitGroup wg.Add(1) wg.Wait() }
空 select
select{}
是一個沒有任何 case
的 select
,它會一直阻塞
package main func main() { select{} }
死迴圈
雖然能阻塞,但會 100%佔用一個 cpu。不建議使用
package main func main() { for {} }
用 sync.Mutex
一個已經鎖了的鎖,再鎖一次會一直阻塞,這個不建議使用
package main import "sync" func main() { var m sync.Mutex m.Lock() }
os.Signal
系統訊號量,在 go 裡面也是個 channel,在收到特定的訊息之前一直阻塞
package main import ( "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 main func main() { c := make(chan struct{}) <-c }
package main func main() { var c chan struct{} //nil channel <-c }
總結
注意上面寫的的程式碼大部分不能直接執行,都會 panic
,提示 “all goroutines are asleep - deadlock!”
,因為 go 的 runtime
會檢查你所有的 goroutine
都卡住了, 沒有一個要執行。
你可以在阻塞程式碼前面加上一個或多個你自己業務邏輯的 goroutine
,這樣就不會 deadlock
了。
文章參考:https://pliutau.com/different-ways-to-block-go-runtime-forever/
「其他文章」
- GoBatch簡介 —— 一款基於go語言的企業級批處理框架(Golang下的SpringBatch)
- Go語言愛好者週刊:第 144 期 — 一道切片的題目
- Wind分散式遊戲伺服器引擎的實現
- Go專案實戰之日誌必備篇[開源十年專案第11次更新]
- 深入Go底層原理,重寫Redis中介軟體實戰
- 從原始碼解讀切片容量增加的計算步驟
- 什麼是中介軟體
- 優維低程式碼:Storyboard 整體結構與路由配置
- 優維低程式碼:事件與互動
- 優維低程式碼:對接後臺資料 !
- Go專案實戰之無限級結構樹形資料格式(易擴充套件方式)【goshop開源專案 | 20220430更新】
- 一種優雅的Golang的庫外掛註冊載入機制
- 優維低程式碼:如何構建第一個微應用?
- Go專案實戰之開發完善分頁外掛(易擴充套件方式)-------【goshop開源專案】【第12次更新】
- 優維低程式碼:關於Brick Next
- Go語言愛好者週刊:第 141 期
- 你知道什麼是Go語言程式設計思維嗎?【文末送 Go 新書】
- 一課玩轉自動化運維全流程,輕鬆應對自動化運維崗
- 破解JavaScript高階玩法,成為精通 JS 的原生專家
- Android面試超級攻略,全面攻破技術疑難及面試痛點