You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go并发执行多个返回bool的校验函数取首个false出现死锁如何解决?

问题根因分析
  • 死锁第一个触发点:启动校验任务的匿名函数是同步执行的,没有为它开启单独goroutine。无缓冲通道q在写入时必须有对应的goroutine同时读取,此时receive函数还未开始接收q的信号,主goroutine直接卡在q <- true位置,后续所有通道读写都无法执行。
  • 死锁第二个触发点:无缓冲通道c每次写入必须有对应的接收方,当receive函数提前返回(比如拿到第一个false)或者只接收1个结果就退出,剩下的校验goroutine尝试往c写入结果时永远找不到接收方,会永久阻塞,导致wg.Wait()永远无法完成。
修复方案

核心调整逻辑如下:

  1. 将启动校验任务的逻辑放到独立goroutine执行,避免阻塞主流程
  2. 给c通道设置等于校验函数数量的缓冲,就算没有接收方,写入也不会阻塞
  3. 移除冗余的q通道,所有校验任务执行完成后直接关闭c通道,通知接收逻辑所有任务已跑完
  4. 新增context取消信号,拿到第一个false结果后通知剩余未执行完的校验任务提前退出,节省资源

修复后可正常运行的代码:

package main

import (
	"context"
	"fmt"
	"sync"
	"time"
)

var wg sync.WaitGroup

func main() {
	v := []func(ctx context.Context, c chan<- bool){
		a1,
		a2,
		a3,
	}
	// 通道缓冲大小等于校验函数数量,写入不阻塞
	c := make(chan bool, len(v))
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// 启动校验任务的逻辑放到独立goroutine
	go func() {
		for _, f := range v {
			wg.Add(1)
			go f(ctx, c)
		}
		// 所有校验任务跑完后关闭通道
		wg.Wait()
		close(c)
	}()

	p := receive(ctx, cancel, c)
	fmt.Println("校验结果:", p)
}

func receive(ctx context.Context, cancel context.CancelFunc, c chan bool) bool {
	for v := range c {
		if !v {
			// 拿到第一个false,提前取消所有剩余校验任务
			cancel()
			fmt.Println("Received ", v)
			return false
		}
	}
	// 通道关闭说明所有校验都通过
	fmt.Println("所有校验通过")
	return true
}

func a1(ctx context.Context, c chan<- bool) {
	defer wg.Done()
	select {
	case <-ctx.Done():
		// 已经有失败的校验了,直接退出
		fmt.Println("a1 提前退出")
		return
	case <-time.After(time.Millisecond * 2000):
		c <- true
		fmt.Println("Finish 1")
	}
}

func a2(ctx context.Context, c chan<- bool) {
	defer wg.Done()
	select {
	case <-ctx.Done():
		fmt.Println("a2 提前退出")
		return
	case <-time.After(time.Millisecond * 2000):
		c <- true // 测试提前退出场景可改为false
		fmt.Println("Finish 2")
	}
}

func a3(ctx context.Context, c chan<- bool) {
	defer wg.Done()
	select {
	case <-ctx.Done():
		fmt.Println("a3 提前退出")
		return
	case <-time.After(time.Millisecond * 2000):
		c <- true
		fmt.Println("Finish 3")
	}
}

内容的提问来源于stack exchange,提问作者Raphael Salomao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 11:36:02