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

Go Worker Pool并发问题:sendOTP中phnno无法正常打印

问题原因分析

1. 主程序提前退出,Worker未完成执行

当启动10000个goroutine时,主goroutine可能在所有Worker还没来得及执行fmt.Println(phnno)就直接终止了。Go程序的规则是主goroutine结束即终止整个程序,不会等待其他goroutine完成。而Worker数量较少时,主goroutine退出前,大部分Worker已经执行完输出逻辑,所以能正常看到结果。

你可以检查代码里是否用了sync.WaitGroup等待所有Worker完成,或是主goroutine在分发完任务后直接结束,没有做阻塞等待。

2. 标准输出缓冲未及时刷新

Go的os.Stdout是带缓冲的,当大量goroutine同时输出时,缓冲内容可能还没来得及刷到控制台,程序就已经退出了。少量Worker场景下,要么缓冲很快被填满自动刷新,要么程序退出前刚好触发了刷新,所以输出能正常显示。

解决方式:在sendOTP的输出语句后手动调用fmt.Flush(),或是改用os.Stderr输出——标准错误流是无缓冲的,内容会直接打印到控制台。

3. 任务队列或Worker逻辑存在问题

如果任务channel容量太小,主goroutine往队列塞任务时可能阻塞,若未处理好阻塞逻辑,部分任务可能无法被Worker接收,自然不会输出。另外,若主goroutine未正确关闭任务channel,Worker可能一直阻塞在读取操作上,没机会执行输出。

你可以检查任务channel的容量是否足够容纳所有任务,或是主goroutine在发完任务后是否及时关闭channel,让Worker知道没有新任务需要处理。

4. 调度压力导致部分Worker未被执行

虽然Go的goroutine轻量,但10000个同时运行时,调度器压力会增大,可能部分goroutine还没轮到被调度执行,程序就已经退出了。不过这个情况相对少见,核心问题还是主goroutine提前退出的概率更高。

常见修复方法
  • 用WaitGroup等待所有Worker完成:启动Worker前调用wg.Add(workerCount),每个Worker执行完后调用wg.Done(),主goroutine最后调用wg.Wait(),确保所有Worker执行完毕再退出。
  • 强制刷新输出缓冲:在sendOTP输出phnno后添加fmt.Flush();或是直接用os.Stderr.WriteString(phnno + "\n")输出,跳过缓冲环节。
  • 正确管理任务channel:确保任务channel容量足够容纳所有任务,或主goroutine发完任务后及时关闭channel,让Worker能正常退出循环。

举个简单的修复示例代码:

package main

import (
	"fmt"
	"sync"
)

func sendOTP(phnno string, wg *sync.WaitGroup) {
	defer wg.Done()
	fmt.Println(phnno)
	// 可选:手动刷新缓冲
	// fmt.Flush()
}

func main() {
	workerCount := 10000
	tasks := make(chan string, workerCount) // 容量与任务数一致,避免阻塞
	var wg sync.WaitGroup

	// 启动Worker池
	for i := 0; i < workerCount; i++ {
		wg.Add(1)
		go func() {
			// 循环读取任务直到channel关闭
			for phnno := range tasks {
				sendOTP(phnno, &wg)
			}
		}()
	}

	// 生成并发送任务
	for i := 0; i < workerCount; i++ {
		tasks <- fmt.Sprintf("phone-%d", i)
	}
	close(tasks) // 关闭任务channel,通知Worker无新任务

	wg.Wait() // 等待所有Worker完成任务
}

内容的提问来源于stack exchange,提问作者Adarsh Shahi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 16:35:18