天天看點

golang 避免程式出現死循環

package main

import (
	"fmt"
	"time"
)

func main() {
	// 業務邏輯
	// 假設目前的業務需要循環對array進行指派
	var array []int
	startParam := 0

	doneChan := make(chan struct{}, 1) // channel通知任務完成
	NoCircleRange(doneChan, time.Second*5, func() { // 安全的循環
		/*****業務邏輯 (循環體)****/
		array = append(array, startParam)
		startParam++
		
		// 循環退出條件
		if startParam == 10 {
			doneChan <- struct{}{}
		}
	})
	// 業務執行完成 繼續處理
	fmt.Println(array)
}

// NoCircleRange 防止for循環出現死循環
/******
* fun 函數應該是循環體内容
* 循環體應保證不會阻塞
* fun 函數體應該由業務邏輯和退出條件兩部分組成
 */
func NoCircleRange(done chan struct{}, maxExec time.Duration, fun func()) {
	signChan := time.After(maxExec)
	for {
		fun()
		select {
		case <-signChan: // 執行逾時
			panic("[NoCircleRange] func execute time out")
		case <-done: // 函數執行完成
			// channel 資源在沒有被goroutine引用時,會自動被GC回收 無關是否關閉
			// 關閉channel可以通知到使用此channel的goroutine 此場景下無需通知
			close(done)
			return
		default:
			continue
		}
	}
}