亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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

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

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 關注
  • 234 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號