子goroutine未接收来自父通道的消息

子goroutine未接收来自父通道的消息,go,concurrency,goroutine,Go,Concurrency,Goroutine,我有一个服务器,在收到请求时需要使用goroutine从不同的流读取消息,将它们发送到父goroutine,父goroutine聚合消息并将它们发送到客户端。所以它将是这样的: 客户端->API->处理程序->worker1 |->工人2 |->工人3 我使用不同的通道在所有这些goroutine之间进行通信,工作人员可以写入聚合通道,处理程序父goroutine可以接收并将其发送回客户端,因此一切正常,几乎: 问题是我的工作人员没有收到处理程序在通道上发送的消息,工作人员的goroutines

我有一个服务器,在收到请求时需要使用goroutine从不同的流读取消息,将它们发送到父goroutine,父goroutine聚合消息并将它们发送到客户端。所以它将是这样的:

客户端->API->处理程序->worker1 |->工人2 |->工人3 我使用不同的通道在所有这些goroutine之间进行通信,工作人员可以写入聚合通道,处理程序父goroutine可以接收并将其发送回客户端,因此一切正常,几乎:

问题是我的工作人员没有收到处理程序在通道上发送的消息,工作人员的goroutines从未停止,但我找不到他们为什么没有收到消息

因为代码太大了,我只把代码的相关部分放进去

注: loglistenmgm是我需要在workers中接收其消息的通道,它有一个与Worker数相同大小的缓冲区,但如果我删除缓冲区,则在写入true后,信息日志将永远不会打印出来,这意味着没有goroutine侦听,我只会在日志和挂在那里的日志中看到这一点:

INFO[0010] Request.Context().Done triggered             
INFO[0010] **Sending true event to loglistenmgm: 0
我的经纪人:

函数处理程序{ logStream:=makechan字符串 完成:=makechan bool,5 loglistenmgm:=makechan bool,numberOfPods errorStream:=makechan错误 对于_,吊舱:=范围吊舱{ 转到getOnePodLogslogStream、errorStream、loglistenmgm,完成 } 围棋{ 为了{ 挑选{ case指出问题是stream.Read,它阻止了select,因此我找到了问题并解决了它

stream.Read是一个io.ReadCloser,频率较低,因此当我将true事件发送到loglistenmgm通道时,工作进程正在等待从stream.Read通道接收新消息,但无法从loglistenmgm通道读取。我通过在处理程序关闭几分钟后将一些消息发送到stream.Read通道来确认这一点,然后工作进程可以继续从频道读取并退出


我通过更改我的程序解决了这个问题,我没有在worker中创建流,而是在处理程序中创建流并将其传递给worker,当我使用完处理程序后,我关闭所有流,这会触发numBytes==0并关闭worker。

从这里的示例很难判断,但首先我要做的是当您处于意外状态时,要做的是查看堆栈跟踪,并查看所有内容被阻止的位置。使用一组这样的通道总是可能导致goroutine之间的同步错误。我建议您努力简化此设计,避免尝试通过done和loglistenmgm等通道在goroutine之间发送信号,以及prefr像WaitGroup和Context这样的东西来控制goroutine。我确切地知道问题在哪里,但不知道为什么会发生以及如何解决。问题是处理程序父goroutine将true发送给loglistenmgm,但工作人员在loglistenmgm上没有收到任何消息。我将查看上下文。我们知道消息不会丢失,因为s的工作,所以一定有东西处于您不期望的状态,这就是我试图描述的问题。最有可能的候选者是您在stream中被阻止。Read,这意味着您将永远无法脱离默认情况来检查loglistenmgm上的消息。关于stream,您可能是对的。Read因为频率该流中的消息数量没有那么高。我尝试了sync.WaitGroup,我添加了所有必需的代码,但它不起作用,最后它也阻止了处理程序goroutine。是否有其他方法杀死这些工作人员?sync.WaitGroup是等待goroutines返回,它不会解决您的问题。如何停止灌浆是完全正确的这取决于podLogRequest.Stream是什么。