为了账号安全,请及时绑定邮箱和手机立即绑定

Go Channels - 推送到通道会停止执行

Go Channels - 推送到通道会停止执行

Go
慕雪6442864 2023-08-07 11:07:39
我正在尝试创建一个命令行测验,用户将被问到一个又一个问题,直到他们完成最后一个问题或超时。我想使用渠道,这样我就可以学习如何正确使用它们,可以说,我遇到了障碍。CorrectAnswersCh 的想法是从 0 开始,每次正确答案后,它都会增加 1。在我将零放入通道后,测验始终停止在 quiz() 函数的第 3 行。我在下面添加了一些代码,但完整的代码在这里: https://play.golang.org/p/vzRCTc7MpIKfunc main() {    questions, err := getCsvData()    var limit = time.Duration(3)    flag.Parse()    if err != nil {        log.Fatal(err)    }    quizComplete := make(chan bool)    correctAnswersCh := make(chan int)    go quiz(quizComplete, questions, correctAnswersCh)    select {    case <-time.After(limit*time.Second):        fmt.Println("Timed Out")    }    fmt.Printf("Correct Answers: %v\n", <-correctAnswersCh)}func quiz(quizComplete chan bool, questions [][]string, correctAnswersCh chan int) {    reader := bufio.NewReader(os.Stdin)    correctAnswersCh <- 0    // execution stops here.  0 is added to correctAnswersCh, then the quiz func stops    for _, question := range questions {        fmt.Print(question[0], "= ")        answer, _ := reader.ReadString('\n')        if strings.TrimSpace(answer) == question[1] {            cA := <-correctAnswersCh            cA++            correctAnswersCh <- cA        }    }    quizComplete <- true}
查看完整描述

1 回答

?
守着星空守着你

TA贡献1799条经验 获得超8个赞

您的correctAnswersCh频道是无缓冲的,因此在其中发送任何内容都会受到阻塞,直到有人从其中接收为止。由于您的main()函数仅在超时后接收来自它的信息,因此在此之前您的应用程序将被阻止。

一种简单的解决方法是为通道提供 1 个缓冲区:

correctAnswersCh := make(chan int, 1)

尽管这是渠道的一些奇怪用法。如果您的目的是创建并发安全计数器,请使用 aotmic 计数器,例如atomic.AddInt32()。另一种选择是在从多个 goroutine 并发访问时使用互斥体(sync.Mutexsync.RWMutex)来保护资源(变量)。


查看完整回答
反对 回复 2023-08-07
  • 1 回答
  • 0 关注
  • 113 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信