gpt4 book ai didi

go - 如何在 Golang 中正确处理缓冲 channel ?

转载 作者:IT王子 更新时间:2023-10-29 02:23:04 25 4
gpt4 key购买 nike

我有一个存储接收数据的 channel ,我想在满足以下条件之一时处理它:
1、 channel 满载。
2,自上次处理后触发计时器。

我看到帖子了 Golang - How to know a buffered channel is full

更新:

我从那个帖子和 OneOfOne 的建议中得到启发,这里是 play :

package main

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

var c chan int
var timer *time.Timer

const (
capacity = 5
timerDration = 3
)

func main() {
c = make(chan int, capacity)
timer = time.NewTimer(time.Second * timerDration)
go checkTimer()
go sendRecords("A")
go sendRecords("B")
go sendRecords("C")

time.Sleep(time.Second * 20)
}

func sendRecords(name string) {
for i := 0; i < 20; i++ {
fmt.Println(name+" sending record....", i)
sendOneRecord(i)
interval := time.Duration(rand.Intn(500))
time.Sleep(time.Millisecond * interval)
}
}

func sendOneRecord(record int) {
select {
case c <- record:
default:
fmt.Println("channel is full !!!")
process()
c <- record
timer.Reset(time.Second * timerDration)
}
}

func checkTimer() {
for {
select {
case <-timer.C:
fmt.Println("3s timer ----------")
process()
timer.Reset(time.Second * timerDration)
}
}
}

func process() {
for i := 0; i < capacity; i++ {
fmt.Println("process......", <-c)
}
}

这似乎工作正常,但我有一个问题,我想在调用 process() 时阻止来自其他 goroutine 的 channel 写入,上面的代码是否能够这样做?或者我应该在 process 方法的开头添加一个互斥量?

任何优雅的解决方案?

最佳答案

正如@OneOfOne 所提到的,选择确实是检查 channel 是否已满的唯一方法。

如果您正在使用 channel 来实现批处理,您始终可以创建一个无缓冲 channel 并让一个 goroutine 拉取项目并附加到一个 slice 。

当 slice 达到特定大小时,处理项目。

这是一个关于 play 的例子

package main

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

const BATCH_SIZE = 10

func batchProcessor(ch <-chan int) {
batch := make([]int, 0, BATCH_SIZE)
for i := range ch {
batch = append(batch, i)
if len(batch) == BATCH_SIZE {
fmt.Println("Process batch:", batch)
time.Sleep(time.Second)
batch = batch[:0] // trim back to zero size
}
}
fmt.Println("Process last batch:", batch)
}
func main() {
var wg sync.WaitGroup
ch := make(chan int)
wg.Add(1)
go func() {
batchProcessor(ch)
wg.Done()
}()
fmt.Println("Submitting tasks")
for i := 0; i < 55; i++ {
ch <- i
}
close(ch)
wg.Wait()
}

关于go - 如何在 Golang 中正确处理缓冲 channel ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38417297/

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