gpt4 book ai didi

go - 匿名函数中的该例程如何工作?

转载 作者:行者123 更新时间:2023-12-02 11:26:32 24 4
gpt4 key购买 nike

func (s *server) send(m *message) error {
go func() {
s.outgoingMessageChan <- message
}()
return nil
}

func main(s *server) {
for {
select {
case <-someChannel:
// do something
case msg := <-s.outGoingMessageChan:
// take message sent from "send" and do something
}
}
}
我在另一个函数中退出了这个 s.outgoingMessageChan,在使用匿名go函数之前,通常会阻止对该函数的调用-这意味着,每当调用 send时, s.outgoingMessageChan <- message就会阻止,直到有东西退出。但是,在像这样包装之后,它似乎不再阻塞了。我知道它会将这种操作发送到后台并照常进行,但是我无法确定这不会影响当前函数调用。

最佳答案

每次调用send时,都会创建一个新的goroutine,并立即返回。 (顺便说一句,如果永远都不会发生错误,则没有理由返回错误。)如果没有任何东西可以从chan中读取(假设它没有缓冲),则goroutine(具有自己的执行“线程”)将阻塞。一旦从chan中读取了消息,goroutine将继续执行,但是由于它什么也不做,它将简单地结束。
我应该指出,没有像匿名goroutine这样的东西。 Goroutine根本没有标识符(除了只能用于调试目的的数字)。您有一个匿名函数,将go关键字放在前面,使它在单独的goroutine中运行。
对于发送函数,它可以按照您的意愿进行阻止,则只需使用:

func (s *server) send(m *message) {
s.outgoingMessageChan <- message
}
但是,我看不到此函数的任何要点(尽管它是内联的,并且与不使用函数一样有效)。
我怀疑您可能在从chan读取任何内容之前多次调用 send。在这种情况下,将创建许多新的goroutine(每次调用 send),这些例程将全部阻塞。每次从chan中读取chan都会取消阻止传递其值,并且goroutine将终止。这样做只是在创建效率低下的缓冲机制。而且,如果以比从chan读取值更快的速率长时间调用 send,那么最终将耗尽内存。最好使用一个缓冲 channel (不使用goroutine),一旦该 channel ( channel )变满,它将对产生消息的任何对象施加“背压”。
另一个要点是,函数名称 main用于标识程序的入口点。请为上面的第二个功能使用其他名称。似乎也应该是方法(使用 s *server接收器)而不是函数。

关于go - 匿名函数中的该例程如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64092460/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com