当我在发件人一侧关闭时,为什么仍会慌张地“在关闭的通道上发送”?

xdk:

我有一个stopChan通知发件人关闭频道的通知sync.Once,并确保只有一个发件人可以关闭频道,但是我仍然收到“在关闭的频道上发送”的恐慌,为什么?

func muitiSenderClose() {
    const SenderNum = 3

    wg := sync.WaitGroup{}
    wg.Add(SenderNum)

    intChan := make(chan int)

    stopChan := make(chan struct{})

    once := sync.Once{}
    for i := 0; i < SenderNum; i++ {
        go func(i int) {
            defer wg.Done()
            needStop := false
            for {
                select {
                case <-stopChan:
                    needStop = true
                case intChan <- 1:
                case intChan <- 2:
                case intChan <- 3:
                }

                if needStop {
                    break
                }
            }
            once.Do(func() {
                fmt.Printf("%d want to close chan\n",i)
                close(intChan)
            })
            fmt.Println("End. [sender] %id", i)
        }(i)
    }
    sum := 0
    for e := range intChan {
        fmt.Printf("Receive %d\n", e)
        sum += e
        if sum > 10 {
            close(stopChan)
            fmt.Printf("Got %d\n", sum)
            break
        }
    }
    fmt.Println("End. [receiver]")

    wg.Wait()
}
colm.anseo:

go并发功能非常强大。协调并发非常 困难幸运的是,go标准库提供了许多工具来帮助实现这一目标。您可能应该熟悉该context软件包。

context.Context在幕后使用完工通道(类似于您的stopChan),但具有取消链接等其他机制。它们在整个go标准库中也用于HTTP,数据库和其他阻止类型的请求。

正如@JimB所提到的,sync.Once在协调生产者/消费者时通常很少需要。chans和sync.WaitGroups通常就足够了。

无论如何,这是使用context.Context以下代码的协调修复

https://play.golang.org/p/QwszE_bW41X

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从 phpmailer 发送时,为什么我的发件人被 postfix 拒绝?

Akka关闭发件人

在关闭事件中处理发件人对象

为什么发件人不向RabbitMQ中的队列发送数据?

使用 setockopt;当套接字从另一侧关闭时,read 返回 0 而不是 -1

发送方通道一侧的MQ是否验证接收方通道一侧的MQ证书?

为什么我的angular / express nodemailer不包含电子邮件的“发件人”部分?

发送邮件时发件人是哪个对象?

发件人离线时如何发送XMPP消息?

为什么我在等待后关闭通道时让所有 goroutines 都睡着了?

为什么发件人会一直忽略 MX 偏好?

为什么发件人的行为就像已被byref传递一样?

为什么未针对发件人验证SPF?

为什么电子邮件允许发件人模拟?

当我在 pyqt5 中使用 Slider 时,为什么我的程序正在关闭?

为什么当我点击项目时我的应用程序会强制关闭?

当我尝试扩展模型属性时,为什么Visual Studio 2013调试器没有错误地关闭?

如果procmail遇到退出代码,为什么会向发件人发送入站邮件的副本?

尽管我在发送所有值后尝试关闭通道,但为什么会出现死锁

当我单击控制台上的关闭按钮时,为什么不调用析构函数?

为什么当我导航到其他页面时 Vue 不关闭 websocket 连接?

为什么当我关闭第二个Activity时onActivityResult()不起作用?

当我关闭AppWindow时,为什么不能打开新的AppWindow

当我单击“更新”时,为什么弹出剑道没有关闭?

为什么当我尝试连接反向ssh时将其关闭?

当我按下按钮开始 Toast 时,Java 应用程序关闭。但为什么?

为什么当我使用“ control-c”关闭发送对等端上的套接字时,接收对等端上的套接字保持无限接收”

为什么 WinMerge 隐藏了我的大部分文件,即使我从一侧或另一侧复制了所有更改?

为什么我的按钮不能设置50%的宽度并在每一侧分开?