網站首頁 編程語言 正文
GoLang之使goroutine停止的5種方法
1.goroutine停止介紹
goroutine是Go語言實現并發編程的利器,簡單的一個指令go function就能啟動一個goroutine;
但是,Go語言并沒有提供終止goroutine的接口,也就是說,我們不能從外部去停止一個goroutine,只能由goroutine內部退出(main函數終止除外);
我們有很多情況下需要主動關閉goroutine,如需要實現一個系統自動熔斷的功能就需要主動關閉goroutine
2.goroutine停止的5種方法
2.1使用for-range
for-range從channel上接收值,直到channel關閉,該結構在Go并發編程中很常用,這對于從單一通道上獲取數據去執行某些任務是十分方便的
2.2使用for-select(向退出通道發出退出信號)
當channel比較多時,for-range結構借不是很方便了;
Go語言提供了另外一種和channel相關的語法: select;
select能夠讓goroutine在多個通信操作上等待(可以理解為監聽多個channel);
由于這個特性,for-select結構在Go并發編程中使用的頻率很高;
我在使用Go的開發中,這是我用的最多的一種組合形式:
for {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> select {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> } }
對于for-select結構,一般我會定義一個特定的退出通道,用于接收退出的信號,如quit
2.3使用for-select(關閉退出通道)
當我們就需要向quit通道中發送100次數據,如果再用以上的代碼就很麻煩,有一個很簡單的方法,關閉channel,這樣所有監聽quit channel的goroutine就都會收到關閉信號,上面的代碼只要做一個很小的替換就能工作
2.4使用for-select(關閉多個channel)
如果select上監聽了多個通道,需要所有的通道都關閉后才能結束goroutine,這里就利用select的一個特性,select不會在nil的通道上進行等待,因此將channel賦值為nil即可,此外,還需要利用channel的ok值
var wg sync.WaitGroup func worker(in1, in2 <-chan int) { defer wg.Done() for { select { case v, ok := <-in1: if !ok { fmt.Println("收到退出信號") in1 = nil } // do something fmt.Println(v) case v, ok := <-in2: if !ok { fmt.Println("收到退出信號") in2 = nil } // do something fmt.Println(v) } // select已經結束,我們需要判斷兩個通道的狀態 // 都為nil則結束當前goroutine if in1 == nil && in2 == nil { return } } } func main() { in1 := make(chan int) // 退出通道,接收 in2 := make(chan int) wg.Add(2) go worker(in1, in2) go worker(in2, in2) for i := 0; i < 3; i++ { in1 <- i time.Sleep(1 * time.Second) in2 <- i } close(in1) close(in2) wg.Wait() }
2.5使用context包
context包是官方提供的一個用于控制多個goroutine寫作的包;
使用context的cancel信號,可以終止goroutine的運行,context是可以向下傳遞的
總結
原文鏈接:https://blog.csdn.net/weixin_52690231/article/details/123159765
相關推薦
- 2022-11-25 使用openssl實現私有CA的搭建和證書的頒發_相關技巧
- 2022-04-14 python實現購物車小程序_python
- 2022-02-17 Flutter InAppWebView在showModalBottomSheet中無法滾動
- 2022-09-24 python中的[1:]、[::-1]、X[:,m:n]和X[1,:]的使用_python
- 2022-12-26 React開發進階redux?saga使用原理詳解_React
- 2022-11-19 Django項目中表的查詢的操作_python
- 2022-11-16 python中如何使用函數改變list_python
- 2024-01-27 什么是消息隊列
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支