文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

无论我关闭通道与否,地图缩小都不起效果

2024-04-04 23:19

关注

大家好,今天本人给大家带来文章《无论我关闭通道与否,地图缩小都不起效果》,文中内容主要涉及到,如果你对Golang方面的知识点感兴趣,那就请各位朋友继续看下去吧~希望能真正帮到你们,谢谢!

问题内容

这是家庭作业和初学者问题。因为我发现了一个错误,所以我编辑了这个问题。

我正在尝试从文本中进行并行频率映射,但在最后一个操作(减少映射)中出现错误

到目前为止,代码似乎可以正常工作。

如果我关闭频道,则会收到错误消息: “恐慌:在封闭通道上发送”

如果我不关闭频道,我会得到: “致命错误:所有 goroutine 都在睡觉 - 死锁!”

func WordCount(text string) {

    text = strings.ToLower(text)
    re := regexp.MustCompile("\\w+")
    sentence := re.FindAllString(text, -1)

    numberOfGroups := 4
    piece := len(sentence) / numberOfGroups

    wordChannel := make(chan map[string]int)

    wg := new(sync.WaitGroup)
    wg.Add(numberOfGroups)

    for i := 0; i < numberOfGroups; i ++ {
        go processToCounting(sentence[i*piece:(i+1)*piece], wordChannel, wg)
    }

    wg.Wait()
    fmt.Print(<-wordChannel)
    fmt.Print("\n")

    finalMap := make(map[string]int)
    close(wordChannel)

    for i := 0; i < numberOfGroups; i++ {
        for k, v := range <- wordChannel {
            finalMap[k] += v
        }
    }
}

func processToCounting(textSlice []string, wordChannel chan map[string]int, wg *sync.WaitGroup) {
    freq := make(map[string]int)
    for _, v := range textSlice {
        freq[v]++
    }
    wg.Done()
    wordChannel <- freq
}


解决方案


<强>1。第一个问题:恐慌

如果我关闭通道,我会收到错误:“恐慌:在关闭的通道上发送”

为什么?其中一个 goroutine 正在尝试写入您已在调用(主)goroutine 中关闭的通道。在您的情况下,在 wordcount 函数中。

在当前版本的代码中,panic is not reproducible 带有我的测试语句,但您很容易导致此问题,例如如果您要在 wg.wait() 之前调用 close(wordchannel)

让我们看看 processtocounting 中可能导致 panicbug

wg.done() // tells to the waitgroup that the gouroutine is done (decrements the counter of goroutines)
wordchannel <- freq // trying to write to the channel

这里 wg.done() 在实际写入通道之前向 waitgroup 发出信号,告知 goroutine 是 done。调用 goroutine(wordcount 函数)在某个时刻认为所有 goroutine 都已完成(wg.wait() 行)并关闭通道。但是你的一个尚未完成写入的 goroutine 会尝试写入已关闭的通道。然后你会得到panic

如何修复:

processtocounting 函数中使用 defer

defer wg.done() // triggers wg.done right before the function returns (but after writing to the channel in your case)

阅读内容:

初学者请参阅A Tour of Go / Concurrency

在封闭的通道上发送会导致恐慌。

和文档:close

发送或关闭已关闭的通道会导致运行时恐慌。

<强>2。第二个问题:死锁

如果我不关闭通道,我会得到:“致命错误:所有 goroutine 都在睡觉 - 死锁!”

您有一个从通道读取数据的 for 循环。这个for循环被永远锁定。等待来自通道的新值,但没有人会再在那里写入。

参见 A Tour of Go / Concurrency

循环 for i := range c 重复从通道接收值,直到关闭。

并查看 Channels 的文档

接收器总是阻塞,直到有数据要接收

问题1:为什么close(wordchannel)会触发panic

答:

  1. 在将结果推送到通道之前放置 wg.done()
  2. 该通道是非缓冲通道,这意味着它将被卡住以进行写入,直到有读取为止。但读取会在您关闭通道后发生。顺序是关闭通道 -> 读取通道 -> 写入通道 -> 恐慌

问题2:为什么会出现死锁。

a: fmt.print(<-wordchannel) 从通道读取一条消息,导致最后一个循环无法读取 numberofgroups 消息。它永远等待最后一条消息。

for i := 0; i < numberOfGroups; i++ {
        for k, v := range <- wordChannel {
            finalMap[k] += v
        }
    }

今天关于《无论我关闭通道与否,地图缩小都不起效果》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注编程网公众号!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯