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

我正在尝试创建一个命令行测验,用户将被问到一个又一个问题,直到他们完成最后一个问题或超时。

我想使用渠道,这样我就可以学习如何正确使用它们,可以说,我遇到了障碍。

CorrectAnswersCh 的想法是从 0 开始,每次正确答案后,它都会增加 1。

在我将零放入通道后,测验始终停止在 quiz() 函数的第 3 行。

我在下面添加了一些代码,但完整的代码在这里: https://play.golang.org/p/vzRCTc7MpIK

func 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

}


慕雪6442864
浏览 114回答 1
1回答

守着星空守着你

您的correctAnswersCh频道是无缓冲的,因此在其中发送任何内容都会受到阻塞,直到有人从其中接收为止。由于您的main()函数仅在超时后接收来自它的信息,因此在此之前您的应用程序将被阻止。一种简单的解决方法是为通道提供 1 个缓冲区:correctAnswersCh := make(chan int, 1)尽管这是渠道的一些奇怪用法。如果您的目的是创建并发安全计数器,请使用 aotmic 计数器,例如atomic.AddInt32()。另一种选择是在从多个 goroutine 并发访问时使用互斥体(sync.Mutex或sync.RWMutex)来保护资源(变量)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go