我是GoLang的学习者,正试图尝试和学习Sync包和chan概念 .
Follwoing是我正在运行的代码,并且希望在控制台上打印 Receiving Channel Value ,但是值不会被打印,它有时会打印值但不总是 .
如果我通过chan调整范围而不将其放入go例程中,那么它将打印所有通道值,但失败并显示错误“ fatal error: all goroutines are asleep - deadlock! ”
我尝试使用通道“done”同步通道读取,但在这种情况下,它再次开始失败并出现相同的错误 . 我也尝试了waitGroup API,你可以在我的代码中看到(评论),但这对我也没有用 .
谢谢您的帮助
Source Code:
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)
//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
}
Output: 值:1主要方法已完成
1 回答
使用
WaitGroup
的一个好模式是在发送到 Channels 或使用go
关键字之前调用Add()
,并在从 Channels 接收后调用Done()
. 这样,无论是否发送通道块,您都可以确保Add()
始终被称为导通时间 .我已经更改了您的示例代码来执行此操作:
Go playground link
当然,您还希望使用互斥锁保护
safeOperation.i
(或者它的值将是不可预测的),但这是获得所需输出所需的全部内容 .