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

在控制台上不打印接收通道值

在控制台上不打印接收通道值

Go
温温酱 2021-04-05 17:18:59
我是GoLang的学习者,正在尝试进行实验并了解Sync软件包和chan概念。我正在运行的代码是期望在控制台上打印“接收通道值”的代码,但是该值未得到打印,它有时但并非总是打印该值。如果我不使用chan遍历chan,那么它会打印所有通道值,但会失败,并显示错误“致命错误:所有goroutine都处于睡眠状态-死锁! ”我尝试使用通道“完成”来同步通道读取,但是在这种情况下,它再次因相同的错误而开始失败。我还尝试了waitGroup API,您可以在我的代码中看到它(有注释),但这对我没有用。谢谢您的帮助源代码:package mainimport (    "fmt"    "sync")type safeOperation struct {    i int    sync.Mutex}var wg sync.WaitGroupfunc main() {    so := new(safeOperation)    ch := make(chan int)    //done := make(chan bool)    for i := 0; i < 5; i++ {        go so.Increment(ch)        go so.Decrement(ch)    }    go func() {        //wg.Add(1)        for c := range ch {            fmt.Println("Receiving Channel Value: ", c)        }        //wg.Done()        //done <- true    }()    //wg.Wait()    //<-done    fmt.Println("Value: ", so.GetValue())    fmt.Println("Main method finished")}func (so *safeOperation) Increment(ch chan int) {    //so.Lock()    //defer wg.Done()    so.i++    ch <- so.i    //so.Unlock()}func (so *safeOperation) Decrement(ch chan int) {    //so.Lock()    //defer wg.Done()    so.i--    ch <- so.i    //so.Unlock()}func (so *safeOperation) GetValue() int {    so.Lock()    v := so.i    so.Unlock()    return v}输出: 值:1主要方法完成
查看完整描述

1 回答

?
元芳怎么了

TA贡献1798条经验 获得超7个赞

一个很好的使用方式WaitGroup是Add()在发送到频道之前先调用,或者使用go关键字,Done()在从频道接收后再调用。这样Add(),无论是否在通道块上发送,都可以确保始终按时调用。


我已经更改了您的示例代码来做到这一点:


package main


import (

    "fmt"

    "sync"

)


type safeOperation struct {

    i int

    sync.Mutex

}


var wg sync.WaitGroup


func main() {

    so := new(safeOperation)

    ch := make(chan int)

    for i := 0; i < 5; i++ {

        wg.Add(1)

        go so.Increment(ch)

        wg.Add(1)

        go so.Decrement(ch)

    }


    go func() {

        for c := range ch {

            fmt.Println("Receiving Channel Value: ", c)

            wg.Done()

        }

    }()

    wg.Wait()

    //<-done

    fmt.Println("Value: ", so.GetValue())

    fmt.Println("Main method finished")

}


func (so *safeOperation) Increment(ch chan int) {

    so.i++

    ch <- so.i

}


func (so *safeOperation) Decrement(ch chan int) {

    so.i--

    ch <- so.i

}


func (so *safeOperation) GetValue() int {

    so.Lock()

    v := so.i

    so.Unlock()

    return v

}


当然,您还希望safeOperation.i使用互斥锁进行保护(否则其值将是不可预测的),但这就是获得所需输出所必需的全部操作。


查看完整回答
反对 回复 2021-04-19
  • 1 回答
  • 0 关注
  • 211 浏览
慕课专栏
更多

添加回答

举报

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