首頁 > 軟體

GoLang使goroutine停止的五種方法範例

2022-07-14 22:02:32

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是可以向下傳遞的

總結

到此這篇關於GoLang使goroutine停止的五種方法的文章就介紹到這了,更多相關GoLang goroutine停止內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com