gpt4 book ai didi

go - 无法无限期地写入一个 goroutine 并从另一个 goroutine 中读取

转载 作者:数据小太阳 更新时间:2023-10-29 03:42:13 30 4
gpt4 key购买 nike

我正在学习围棋,但在使用 goroutines 时遇到了问题。这是我的代码

package main

import (
"fmt"
"sync"
"time"
)

var counter = 0
var wg = sync.WaitGroup{}

func main() {
ticker := time.NewTicker(time.Second)
go func() {
for range ticker.C {
// wg.Add(1)
// defer wg.Done()
counter++
fmt.Println(counter)
//wg.Done()
}
}()

ticker2 := time.NewTicker(time.Second * 2)
wg.Add(1)
go func() {
for range ticker2.C {
//defer wg.Done()
fmt.Println(counter)
}
}()
wg.Wait()
}

基本上,我想要:

  • 一个名为counter的全局变量
  • 一个 goroutine 每 1 秒更新一次这个计数器
  • 另一个 goroutine 每两秒打印一次这个计数器

Playground 是 here我试着玩 WaitGroup 但我没能成功。对于这个级别的代码,我有以下警告:

WARNING: DATA RACE
Read at 0x0000011d8318 by goroutine 8:
runtime.convT2E64()

另一个问题这个线程安全吗?我的意思是,我可以在两个 groroutine 之外的 main 方法中安全地使用计数器吗?

最佳答案

一种方法可能是在需要打印时向第二个 gorutine 发送消息。

package main

import (
"fmt"
"time"
)

func main() {

fmt.Println("Start");
counter := 0

printChannel := make( chan int)
done := make(chan struct{} )

go func(done <-chan struct{}, printChannel chan<- int ){
timer := time.NewTicker(time.Second)
bDone := false;
for !bDone {
select {
case <-timer.C:
counter++
if counter%2 == 0 {
printChannel <- counter
}
case <-done:
bDone=true
}
}
}(done, printChannel)

go func(done <-chan struct{}, printChannel <-chan int ){
bDone:=false
for !bDone{
select {
case n := <-printChannel:
fmt.Print(n, " ");
case <-done:
bDone=true
}
}
}(done,printChannel)


//whatever logic to stop
go func() {
<- time.After(21*time.Second)
done <- struct{}{}
}()

<-done

fmt.Println("\nEnd");

}

注意这里有第三个 gorutine 来完成这个例子

输出:

Start
2 4 6 8 10 12 14 16 18 20
End

要改进它,您可以在没有 bDone 变量的情况下进行,您可以停止 Ticker 并在 gorutine 存在时添加适当的消息。或者你可能想用标签测试'break'以退出循环。
您可以使用关闭(完成) channel 而不是向其发送消息来测试效果。
此外,如果您准备放宽读/写顺序,您可以删除 printChannel 并让第二个 gorutine 使用另一个每 2 秒 ping 一次的自动收报机。

关于go - 无法无限期地写入一个 goroutine 并从另一个 goroutine 中读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49617904/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com