Skip to content

sync.WaitGroup增加timeout

Published: at 07:52 AM | 1 min read

要等待多个goroutine完成,我们可以使用sync.WaitGroup,但是它会一直等待,这里简单封装下增加超时机制。

直接上代码:

type WaitGroupTimeout struct {
	wg sync.WaitGroup
	done chan struct{}
	timeout time.Duration
}

func NewWaitGroupTimeout(timeout time.Duration)*WaitGroupTimeout {
	return &WaitGroupTimeout{
		done: make(chan struct{}),
		timeout: timeout,
	}
}

func(tw *WaitGroupTimeout)Add(delta int) {
	tw.wg.Add(delta)
}

func(tw *WaitGroupTimeout)Done() {
	tw.wg.Done()
}

func(tw *WaitGroupTimeout)Wait() {
	go func() {
		tw.wg.Wait()
		close(tw.done)
	}()
	select {
	case <- tw.done:
	case <-time.After(tw.timeout):
	}
}

测试代码如下:

func main() {
	const TIMEOUT = 5 * time.Second
	const TASK_EXECUTE_TIME = 3 * time.Second

	tw := NewWaitGroupTimeout(TIMEOUT)
	go func() {
		tw.Add(1)
		defer tw.Done()
		fmt.Println("start")
		time.Sleep(TASK_EXECUTE_TIME)
		fmt.Println("end")
	}()
	fmt.Println("wait exit")
	tw.Wait()
	fmt.Println("exit")
}

当超时时间大于任务时间时,任务可以正常完成然后退出,
当超时时间小于任务时间时,任务没有执行完成就退出了。