gpt4 book ai didi

go - 当 channel 接收到新值时无限循环被终止

转载 作者:行者123 更新时间:2023-12-01 21:13:43 25 4
gpt4 key购买 nike

我有 2 个模块(模块 1 和模块 2),我在模块 1 中生成一些随机数,并通过 main 中定义的 channel 将它们传递给模块 2。当值落在模块 2 中时,我希望它在循环中打印,直到新值再次从模块 1 到达。这是代码。
main.go文件内容

package main

import (
"time"
"example/module1"
"example/module2"
)

func main() {
ints := make(chan []int, 1)
for {
select {
case <- time.After(5 * time.Second):
go module1.GenerateRandint(ints)
case <- module2.Done:
go module2.Start(ints)
}
}
}
module1的内容如下。
package module1

import (
"math/rand"
"time"
)

func GenerateRandint(a chan []int){
var rint []int
for i:=0;i<1;i++ {
rand.Seed(time.Now().UnixNano())
rint = append(rint, rand.Int())
}
a <- rint
}
module2是:
package module2

import (
"fmt"
"math/rand"
"sync"
"time"
)

var Done = make(chan struct{})
var quit = make(chan struct{})

type localData struct {
nums []int
Lock sync.RWMutex
}

var store localData

func init() {
go func() {
Done <- struct{}{}
quit <- struct{}{}
}()
go printer(0, quit)
}

func printer(id int, quit chan struct{}) {

for {
select {
case <-quit:
return
default:
store.Lock.RLock()
fmt.Println("ID:", id, "====", store.nums)
time.Sleep(500 * time.Millisecond)
store.Lock.RUnlock()

}
}
}

func Start(a chan []int) {
rand.Seed(time.Now().UnixNano())
d := <-a
fmt.Println("RECEIVED DATA", d)
store.Lock.Lock()
go func() {
quit <- struct{}{}
}()
store.nums = d
store.Lock.Unlock()
go printer(rand.Int(), quit)
Done <- struct{}{}

}

在最终输出中,我没有看到 printer功能连续打印 slice 。它打印一次。我在下面粘贴一个示例输出。
ID: 0 ==== []
RECEIVED DATA [5183630848712612481]
ID: 2057228961822266542 ==== [5183630848712612481]
RECEIVED DATA [7203870927705193095]
RECEIVED DATA [1478549829208931483]
ID: 2311909806311895805 ==== [1478549829208931483]
RECEIVED DATA [3000658591728341557]

理想的输出应该是:
ID: 0 ==== []
RECEIVED DATA [5183630848712612481]
ID: 2057228961822266542 ==== [5183630848712612481]
ID: 2057228961822266542 ==== [5183630848712612481]
ID: 2057228961822266542 ==== [5183630848712612481]
ID: 2057228961822266542 ==== [5183630848712612481]
ID: 2057228961822266542 ==== [5183630848712612481]
RECEIVED DATA [7203870927705193095]
ID: 3052382001843759201 ==== [7203870927705193095]
ID: 3052382001843759201 ==== [7203870927705193095]
ID: 3052382001843759201 ==== [7203870927705193095]
ID: 3052382001843759201 ==== [7203870927705193095]
ID: 3052382001843759201 ==== [7203870927705193095]
RECEIVED DATA [1478549829208931483]
ID: 3850200927174591249 ==== [1478549829208931483]
ID: 3850200927174591249 ==== [1478549829208931483]
ID: 3850200927174591249 ==== [1478549829208931483]
ID: 3850200927174591249 ==== [1478549829208931483]
ID: 3850200927174591249 ==== [1478549829208931483]
RECEIVED DATA [3000658591728341557]

最佳答案

我将假设您正在询问有关调用 go printer(0, quit) 的问题。在 init()功能。它只打印整个列表一次的原因是:

在 init() 函数中,您尝试将数据发送到 Donequit channel 。现在,它们显然会阻塞,直到接收器准备好。加载模块后,接收器尚未准备好,因此您转到 default打印机方法中的情况。因此,它打印该语句一次并休眠 500 毫秒。在此期间,main()启动并为 Done 创建一个接收器 channel 。这会解除对该 channel 的写入阻塞,随后会写入 quit。 channel 也是如此。现在,自从 quit也有数据,printer中的select语句方法简单地返回,不再打印。

关于go - 当 channel 接收到新值时无限循环被终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61857989/

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